day4 快慢指针的用法以及理解Floyd-cycle算法

问题:给你一个链表头,如何判断这个链表里面是否存在环?用快慢指针,为什么快慢指针能找到环呢?
想不明白就把这个环展开,_____ | _____ | _____只要存在速度差,走得快的一定能赶上速度慢的,在换上标记坐标,0,1, 2,3...n-1, 0, 1, ... 每个坐标表示一个位置,小明(慢)和小红(快)都从0开始出发,相遇的时候,小明走的路程是x+y, 小红走的路程是x+y+n(z+y), 现在已知快的速度是慢的两倍,所以路程也是两倍的关系,于是有\(2\times (x+y+m \times C) = x + n \times C + y\) 整理得到\(x+y=C\times c^'\)
然后就有$$ x=C
c'-y=(C-1) \times c + z = C_3 c + z $$
现在这个表达式的意思就是x大小是z加上若干倍的一整圈,如果我们让一个指针p1从头开始走,另一个指针p2从相遇点开始走,就意味着当p1走到环入口的时候,p2走了z+若干倍的环,这是不是就意味着这两个指针恰好在入口能相遇啊,这样我们也就找到了环。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head == nullptr) {
            return nullptr;
        }
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast->next && fast->next->next) {
            fast = fast->next->next;
            slow = slow->next;
            if(slow == fast) {
                auto p1 = slow;
                auto p2 = head;
                while(p1 != p2) {
                    p1 = p1->next;
                    p2 = p2->next;
                }
                return p1;
            }
        }
        return nullptr;
    }
};
posted @ 2023-12-30 16:01  ccnju  阅读(10)  评论(0)    收藏  举报