https://oj.leetcode.com/problems/linked-list-cycle/
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
public boolean hasCycle(ListNode head)
为了假装我不是事先知道解的。我先给一个很直观的O(N^2)的算法吧。给一个tmp指针,做两重循环,第一个外层循环tmp每次都往下走,第二个循环里设一个tmp_2指针,从头走碰到tmp停。统计tmp走的步数和tmp_2走的步数,如果不等则是循环。或者tmp走到空指针则不是循环。
public boolean hasCycle(ListNode head) {
ListNode tmp = head;
int ctr = 0;
while(tmp != null){
int ctr_2 = 0;
ListNode tmp_2 = head;
while(tmp_2 != tmp){
tmp_2 = tmp_2.next;
ctr_2++;
}
if(ctr_2 != ctr)
return true;
ctr++;
tmp = tmp.next;
}
return false;
}大家不用试了,这代码在某个大数据的时候TLE,因为这一题oj估计只能接受ON的做法。
O(N)的做法我相信很多人应该都懂了,但我还是说一下,快慢指针,快指针每次走两步,慢指针每次走一步。当慢指针最终遇见了快指针,则表示true,否则快指针先行走到了null,那表示false。给出代码如下:
public boolean hasCycle(ListNode head) {
ListNode slow = head, fast = head;
while(slow != null && fast != null){
slow = slow.next;
fast = fast.next;
fast = fast != null ? fast.next : fast;
if(fast != null && fast == slow)
return true;
}
return false;
}当然还有另一个傻一点的O(N)的做法,哈希表记录走过的节点。当遇到重复的便是循环,否则不是,这做法太直观,我就不写了,肯定能过的。。
本文介绍两种链表中是否存在循环的检测方法:一种是通过快慢指针的方式进行判断,另一种是采用双指针遍历的方法。前者利用快慢指针速度差来检测循环,后者通过比较内外层指针移动距离来确定。
374

被折叠的 条评论
为什么被折叠?



