劍指offer:連結串列中環的入口節點
阿新 • • 發佈:2018-12-31
題目:如果一個連結串列中包含環,找出環的入口節點。
思考:如果一個連結串列有環,用一個指標遍歷將永遠也走不到盡頭。若用兩個指標遍歷:快指標每次走一步,慢指標每次走兩步。如果快指標走到了連結串列的末尾都沒有追上慢指標,則沒有環。如果快指標追上了慢指標,則有環。
如圖:
一個帶環的連結串列,環內節點個數為4.
步驟:
a) 指標pfast,pslow初始化時都指向連結串列的第一個節點。
b) 由於環中有4個節點,所以pfast指標先走4步。
c) 快指標,慢指標以相同速度向前移動,直到它們相遇。
再思考:
如何得到環中節點的數目?
1)兩個指標,快指標一次走兩步,慢指標一次走一步,如果倆指標相遇,則說明有環,且相遇的指標一定在環中。
2)設定一個指標從相遇點開始遍歷環內節點並計數,待再次回到這個節點時,就可以得到環內節點個數。
如何找到入口節點?
1)兩個指標從頭遍歷,讓快指標先走“節點的個數”步,然後快慢指標同時走,待相遇時,即是入口節點。
Node* JudgeIfCircle(Node* pHead)//判斷是否有環 { if(pHead == NULL || pHead->pnext == NULL) { return NULL; } Node* pfast = pHead->pnext->pnext; Node* pslow = pHead->pnext; while(pslow != pfast) { pfast = pfast->pnext->pnext; pslow = pslow->pnext; } return pfast; } Node* EntryNode(Node* pHead) { Node* meetNode = JudgeIfCircle(pHead); if (meetNode == NULL) { return NULL; } Node* pCur= meetNode; /*int count = 0; while (pCur != meetNode)//迴圈進不去 { pCur = pCur -> pnext; count++; }*/ int count = 1; while(pCur->pnext!= meetNode)//查詢環中幾個節點 { pCur = pCur->pnext; count++; } Node* pfast = pHead->pnext; Node* pslow = pfast;//使兩個指標指向第一個節點 for (int i = 0; i < count; i++)//快指標先走count步 { pfast = pfast->pnext; } while (pslow != pfast) { pfast = pfast->pnext; pslow = pslow->pnext; } return pfast; }