8.找出链表环的入口结点
題目描述
給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,否則,輸出null。
/* struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} }; */ class Solution { public:ListNode* EntryNodeOfLoop(ListNode* pHead){} };鏈表中有環的解釋:參考:http://blog.sina.com.cn/s/blog_a1ce3d4b0102wks6.html
上圖中的第二個示例圖P2改為P1。
環中結點的數目
1)判斷一個鏈表里是否有環時用到了一快一慢兩個指針,如果兩個指針相遇,表明鏈表中存在環。兩個指針相遇的結點一定在環中,2)從這個結點出發,一邊繼續向前移動一位一遍計數,當再次回到這個結點時,就可以得到環中的節點數。
解法1:
class Solution {//找到一快一滿指針相遇處的節點,相遇的節點一定是在環中public:static ListNode* meetingNode(ListNode* head) {if(head==NULL)return NULL;ListNode* slow = head->next;if(slow==NULL)return NULL;ListNode* fast = slow->next;while (slow != NULL && fast != NULL) {if(slow==fast){return fast;}slow=slow->next;fast=fast->next;if(fast!=slow){fast=fast->next;}}return NULL;}public:ListNode* EntryNodeOfLoop(ListNode* pHead) {ListNode* meetingNode1=meetingNode(pHead);if(meetingNode1==NULL)return NULL; // 得到環中的節點個數int nodesInLoop=1;ListNode* p1=meetingNode1;while(p1->next!=meetingNode1){p1=p1->next;++nodesInLoop;} // 移動p1p1=pHead;for(int i=0;i<nodesInLoop;i++){p1=p1->next;} // 移動p1,p2ListNode* p2=pHead;while(p1!=p2){p1=p1->next;p2=p2->next;}return p1;} };解法2:?出錯!
class Solution { public:ListNode* EntryNodeOfLoop(ListNode* pHead){if(pHead==nullptr||pHead->next==nullptr)return nullptr;ListNode* pSlow=pHead;ListNode* pFast=pHead;while(pFast!=nullptr&&pFast->next!=nullptr){pSlow=pSlow->next;//慢結點走1步pFast=pFast->next->next;//快結點走2步if(pFast==pSlow)return pFast;}return nullptr;} }; // 故上述的這種情況只滿足:環中有結點個數為2的情況測試結果:
您提交的程序沒有通過所有的測試用例
case通過率為50.00%
原因是事前不知道環結點有幾個,就pFast走到了第二個指針。
解法:3:其它的思路
//先說個定理:兩個指針一個fast、一個slow同時從一個鏈表的頭部出發
//fast一次走2步,slow一次走一步,如果該鏈表有環,兩個指針必然在環內相遇
//此時只需要把其中的一個指針重新指向鏈表頭部,另一個不變(還在環內),
//這次兩個指針一次走一步,相遇的地方就是入口節點。
//https://blog.csdn.net/snow_7/article/details/52181049
https://blog.csdn.net/WitsMakeMen/article/details/37597291
通過!
但是沒有像之前說的要找出結點的個數!
類似解法:
//左神講的 //先說個定理:兩個指針一個fast、一個slow同時從一個鏈表的頭部出發 //fast一次走2步,slow一次走一步,如果該鏈表有環,兩個指針必然在環內相遇 //此時只需要把其中的一個指針重新指向鏈表頭部,另一個不變(還在環內), //這次兩個指針一次走一步,相遇的地方就是入口節點。 //這個定理可以自己去網上看看證明。https://blog.csdn.net/snow_7/article/details/52181049 //https://www.cnblogs.com/snake-hand/p/3148328.html class Solution {public: ListNode* EntryNodeOfLoop(ListNode* pHead){ListNode* fast = pHead;ListNode* slow = pHead;while(fast != NULL && fast->next !=NULL){fast = fast->next->next;slow = slow->next;if(fast == slow)break;}if(fast == NULL || fast->next == NULL)return NULL;fast=pHead;while(fast!=slow){fast=fast->next;slow=slow->next;}return fast;} };?
參考:
【1】https://www.nowcoder.com/questionTerminal/253d2c59ec3e4bc68da16833f79a38e4
【2】思路2的定理?https://blog.csdn.net/WitsMakeMen/article/details/37597291?待續
總結
以上是生活随笔為你收集整理的8.找出链表环的入口结点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 认清电脑配件保修规定 不吃哑巴亏!
- 下一篇: JAVA java学习(46)—————