Skip to content
高琦程 Gao Qicheng
Go back

链表(2)

Edit page

快慢指针法

本质在于“相对速度”,用速度差来刻画路径长度。

比如——

环形链表

找到环形链表里的环有两种思路。

一种非常直接,用一个 unordered_set 存一下所有的 Node*,然后开始遍历链表。如果遇到重复就return。


class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        unordered_set<ListNode*> visited;
        ListNode* cur = head;
        while(cur!=nullptr){
            if(visited.count(cur)){
                return cur;
            }

            visited.insert(cur);
            cur = cur->next;
        }

        return nullptr;
    }
};

//对应LC142

另一种则是快慢指针法,在内存上做了极致的优化。


class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if (head == nullptr || head->next == nullptr) return nullptr;

        ListNode* slow = head;
        ListNode* fast = head;
        
        while (fast != nullptr && fast->next != nullptr) {
            slow = slow->next;        // 慢指针走1步
            fast = fast->next->next;  // 快指针走2步
            
            // 找到第一个相遇点
            if (slow == fast) {
                // 一个指针放回头节点,另一个留在相遇点
                ListNode* ptr1 = head; // 从头走
                ListNode* ptr2 = slow; // 从相遇点走
                while (ptr1 != ptr2) {
                    ptr1 = ptr1->next;
                    ptr2 = ptr2->next;
                }
                // 再次相遇的地方,就是环入口
                return ptr1;
            }
        }
        return nullptr; // 没环
    }
};


Edit page
Share this post:

Previous Post
STL拾遗
Next Post
链表(1)