Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
哈希表求解
简单处理就是将数据存放到哈希表,遍历的过程中判断是否存在,若存在说明有环。但是此算法在空间复杂度和时间复杂度上均为 O(n) ,性能不佳。代码如下:
public class Solution {
public boolean hasCycle(ListNode head) {
Set<ListNode> set = new HashSet<ListNode>();
ListNode temp = head;
while(temp != null) {
if(set.contains(temp))
return true;
else
set.add(temp);
temp = temp.next;
}
return false;
}
}
赛跑算法
也就是Cycle Detection,具体可参考Floyd判圈算法。
Copy 了一段外国人的清晰解释:
Since the runner’s speed is faster than walker, then it is guaranteed that runner will pass walker in some time. The only thing we need to prove is that the runner never jumps over walker so never meet. Suppose the runner jumps over walker in one unit of time, then we need to guarantee that 2 > distance + 1. So distance < 1 so distance = 0. This implies that runner already meets walker, contradiction. So runner will never jumps over walker.
Runner will pass walker + runner never jumps over = runner will meet walker.
时间复杂度不变,但是空间复杂度下降到了 O(1) 。算法如下:
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null) return false;
ListNode slow = head;
ListNode fast = head;
//由于fast遍历速度较快
//所以只判断fast有没有下个节点和下下个节点
while(fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
if(slow == fast) {
return true;
}
}
return false;
}
}