【双指针】(快慢指针)142. 环形链表 II

题目:

 

 方法一:哈希表

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        Set<ListNode> set = new HashSet<>();
        ListNode res =null;
        ListNode p = head;
        while(p!=null){
            if(set.contains(p)){
                res = p;
                break;
            }
            if(!set.contains(p)){
                set.add(p);
            }
            p = p.next;
        }

        return res;
    }
}

 

方法二:快慢指针

 

 快慢指针相遇时:快指针走过的路程= a+n(b+c) + b;慢指针走过的路程=a+b; 设置快指针速度是慢指针的两倍,则有:a+n(b+c) +b = 2(a+b)  =》 a = c + (n-1)(b+c)

当快慢指针相遇后,设置一个指针指向head,让它和慢指针以同样的速度同时前进,先走了c,此时慢指针来到环形链表的入环节点,然后slow指针转(n-1)圈与设置的指针在入环节点处相遇。

 

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head == null){
            return null;
        }
        ListNode slow = head, fast = head;

        while(fast!=null){
            slow = slow.next;
            if(fast.next!=null){
                fast = fast.next.next;
            }else{
                return null;
            }

            if(fast == slow){
                ListNode p = head;
                while(p != slow){
                    p = p.next;
                    slow = slow.next;
                }
                return p;
            }
        }

        return null;
    }
}

 

posted @ 2020-10-24 23:44  3KBLACK  阅读(126)  评论(0)    收藏  举报