环形链表Ⅱ
解法一:
使用HashSet存储每个节点:
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode node = head;
HashSet<ListNode> set = new HashSet<ListNode>();
while (node != null) {
if (set.contains(node)) {
return node;
} else {
set.add(node);
}
node = node.next;
}
return null;
}
}
解法二
使用快慢指针:
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null)
return null;
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (slow == fast) {
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
}
}
标记处思路解析
假设slow 和fast 相遇时,slow 总共走了k步,那么fast 走了2k步,假设圆环长度为h,则k=nh ,也就是说,k是h的整数倍,理由如下: 如上图所示,假设slow 和fast 的相遇点为o ,slow 和fast 同时从head 出发,fast 先到达o 点,然后在环内继续移动,当slow 到达o 点时,fast 刚好也到达,所以fast 的第二个k 步是在环内o 开始,绕环n圈后回到o 点产生的,所以k是环长的整数倍。 这时假设环起点和相遇点的距离为m ,则从head 到环起点的距离为k-m ,此时令fast 从相遇点出发,走k-m 步,正好回到了环起点,在fast 出发的同时,让slow 指针同时从head 出发,步幅相同的情况下,当slow == fast 时,slow 就是环起点。
|