141 Linked List Cycle 判斷是否有環&&142 入環節點
阿新 • • 發佈:2018-11-12
1.是否有環
非常簡單的思路,放進去set中,利用set的find函式遍歷連結串列,看是否出現過以前出現過的節點
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { std::set<ListNode *> node_set; while(head){ if(node_set.find(head)!=node_set.end()){ return true; } node_set.insert(head); head=head->next; } return false; } };
2.入環節點
(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) { std::set<ListNode *> node_set; while(head){ if(node_set.find(head)!=node_set.end()){ return head; } node_set.insert(head); head=head->next; } return NULL; } };
第一種方法,非常簡單,但是它需要額外的空間分配。
(2)第二種方法,不需要分配額外空間
利用快慢指標,首先同時從head出發,快指標走兩步,慢指標走一步,一定會在一個地方相遇。
此時,慢指標走一步,快指標回到head重新出發,也走一步,他們一定會在相遇,此時的節點就是入環的節點。(說是已經被證明,不知道是怎麼證明的哈哈哈哈哈哈哈,有人能告訴我嗎)
/** * 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) { if(head==NULL||head->next==NULL||head->next->next==NULL){ return NULL; } ListNode *fast=head; ListNode *slow=head; fast=head->next->next; slow=head->next; while(fast!=slow){ if(fast->next==NULL||fast->next->next==NULL){ return NULL; } fast=fast->next->next; slow=slow->next; } fast=head; while(fast!=slow){ fast=fast->next; slow=slow->next; } return fast; } };