日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

8.找出链表环的入口结点

發布時間:2023/12/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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

class Solution {public:ListNode* EntryNodeOfLoop(ListNode* pHead){if(pHead==nullptr|| pHead->next==nullptr|| pHead->next->next==nullptr)return nullptr;ListNode* fast=pHead->next->next;ListNode* slow=pHead->next;//先判斷有沒有環while(fast!=slow){if(fast->next!=nullptr&& fast->next->next!=nullptr){fast=fast->next->next;slow=slow->next;}else{//沒有環,返回return nullptr;}}//跳出上述循環,則有環,此時fast=slow.fast=pHead;//重新定義fast結點的位置為頭結點while(fast!=slow){fast=fast->next;slow=slow->next;}return slow;} };

通過!

但是沒有像之前說的要找出結點的個數!

類似解法:

//左神講的 //先說個定理:兩個指針一個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.找出链表环的入口结点的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。