題目
自己寫的:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *cur = head;
unordered_set<ListNode *>visited;
while (cur)
{
if (visited.count(cur->next))
{
return cur->next;
}
visited.insert(cur);
cur = cur->next;
}
return cur;
}
};
注意這條語句:visited.insert(cur);
,不要寫成 visited.insert(cur->next);
,應該是把當前節點插入雜湊集合,而不是把當前節點的下一個節點插入雜湊集合,因為在看是否有環時,是根據當前節點的下一個節點是否在當前節點的前面節點中來判斷的。
不過,這個解法不是 O(1) 空間。
看了卡哥思路,很巧妙,結合數學分析來解題,有點像小學奧賽。
卡哥影片完美的講述了這個思路,所有小細節都講到了。
卡哥程式碼:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
// 快慢指標相遇,此時從head 和 相遇點,同時查詢直至相遇
if (slow == fast) {
ListNode* index1 = fast;
ListNode* index2 = head;
while (index1 != index2) {
index1 = index1->next;
index2 = index2->next;
}
return index2; // 返回環的入口
}
}
return NULL;
}
};