Loop in List 鍊錶中的圈

2021-06-29 02:22:55 字數 1634 閱讀 7246

q: 給定乙個linked list, 如何判斷這個linked list 中是否有乙個loop。 例如如下圖:

鍊錶的乙個節點定義如下:

struct listnode ;
分析: 這是乙個很有名的面試題。  我們的解法是:

使用兩個指標pfast和pslow, 均初始化為指向煉表頭。 乙個指標一次向前移動1個節點,  另乙個指標一次向前移動兩個節點。  也就是說pfast指標向前移動到的速度是pslow的兩倍。  如果移動快的pfast指標和移動慢的pslow指標相遇了, 就表明list中有乙個loop, 也就是pfast在轉圈圈。 否則, 沒有loop的話, 那麼pfast 必然移動到list 的尾部。 程式如下:

bool hasloop(listnode *phead) 

return false;

}

q2 如果鍊錶中有乙個loop, 如何找到這個loop的entry bide? 乙個loop的entry node就是從list的head走, 遇到的loop的第乙個node。

分析:  兩個指標初始化煉表頭。 如果loop中有n個節點, 那麼我們設定第乙個指標先向前移動n個節點。 然後這兩個指標以相同的步伐向前移動。 當第二個指標到達the entry of the loop, 第乙個指標已經沿著這個loop一圈, 再次回到loop 的entry node,

例如下圖:

如上圖, 指標p1和指標p2首先初始化為指向煉表頭的節點。 由於loop中有四個節點,  所以p1 先走四步。 之後p1, p2在同時向前一次乙個節點的走。

在本例中, 再移動兩步, p1和p2就在loop的entry node 相遇。

問題來了, 如何知道loop的節點數目????

參考第一問, 我們定義了兩個指標, 這兩個指標最終會在loop中的某個節點相遇。我們在接下來, 從相遇的節點處, 停止移動節點pfast, 然後一步乙個節點的移動pslow, 那麼pslow最終再次返回到meeting node 出所經過的節點數就是loop的節點數目。 程式如下:

listnode* meetingnode(listnode *phead) 

return null;

}

接下來, 先求list中的loop的node數目。 然後利用這個資訊求entry node。

listnode* entrynodeofloop(listnode* phead) 

// move pnode1

pnode1 = phead;

for(int i = 0; i < nodesinloop; ++i)

pnode1 = pnode1->next;

// move pnode1 and pnode2

listnode* pnode2 = phead;

while(pnode1 != pnode2)

return pnode1;

}

lintcode 鍊錶 刪除鍊錶中的元素

刪除鍊錶中等於給定值val的所有節點。給出鍊錶 1 2 3 3 4 5 3,和 val 3,你需要返回刪除3之後的鍊錶 1 2 4 5 判斷鍊錶是否為空,若是,返回null,若不是,進行下一步 判斷鍊錶第乙個結點是否為要刪除的結點,若是,將head指標向後移,若不是,無需操作 定義指標pre,判斷當...

鍊錶 刪除鍊錶中重複的節點

刪除鍊錶中重複的節點 方法一 採用遞迴的方法,但這種方法在鍊錶無重複節點時效率不高 function deleteduplication phead if phead.val phead.next.val return deleteduplication node 採用遞迴的方法從下乙個不重複的點開...

鍊錶 1 鍊錶中資料的刪除

這是乙個在鍊錶中刪除特定字元的 學習鍊錶後第一次編寫的乙個 1 include 2 include 3 include 4 include 5 include 6 using namespace std 7structsa8 12int show sa t 列印鍊錶 1319 return0 20 ...