1. 在 o(1)的時間刪除鍊錶節點
題目描述:給定鍊錶的頭指標和乙個節點的指標,在 o(1)時間刪除該節點。
解法:用該節點的下乙個節點覆蓋要刪除的節點,然後刪除下乙個節點。(如果是尾節點就行不通了)
2. 求鍊錶倒數第 k 個節點
題目描述:輸入乙個單向鍊錶,輸出該鍊錶倒數第 k 個節點。
解法:設定兩個指標 p1、p2,首先 p1 和 p2 都指向 head,然後 p2 先走 k 步,此時 p1 和 p2 在同時走,當 p2 走到鍊錶尾的時候,此時 p1 就是倒數第 k 個節點。
3. 求鍊錶的中間節點
題目描述:求鍊錶的中間節點,如果鍊錶長度為偶數,返回中間兩個節點的任意乙個節點,若為奇數,則返回中間節點。
解法:兩個指標,乙個每次走兩步,乙個每次走一步,當走兩步的指標走到鍊錶尾的時候,那麼走一步的指標就走到了中間節點。
4. 判斷單鏈表是否有環
題目描述:輸入乙個單向鍊錶,判斷鍊錶是否有環。
解法:兩個指標,從煉表頭開始,乙個走兩步,乙個走一步,如果存在環,那麼兩個指標必定會在環上相遇。
5. 找到環的入口點
題目描述:輸入乙個單向鍊錶,判斷鍊錶是否有環?如果有環,如何找到環的入口點?
解法:兩個指標 p1、p2,p2 每次走兩步,p1 每次走一步,若發現 p1 和 p2 重合,則可以確定單向鍊錶有環。接下來,讓 p2回到鍊錶的頭部,重新走,每次走一步,那麼當 p1 和 p2 再次相遇的時候,就是環的入口了。
為什麼:假定起點到環入口點的距離為 a,p1 和 p2 的相交點 m 與環入口點的距離為 b,環路的周長為 l,當 p1 和 p2 第一次相遇的時候,假定 p1 走了 n 步。那麼有: p1 走的路徑:a + b = n;
p2 走的路徑:a + b + k * l = 2 * n ; p2 比 p1 多走了 k 圈環路,總路程是 p1 的 2 倍。
根據上述公式可以得到 k * l = a + b = n,顯然,如果從相遇點 m 開始,p1 再走 n 步的話,還可以再回到相遇點,同時 p2 從頭開始走的話,經過 n 步,也會達到相遇點 m。
顯然在這個步驟當中 p1 和 p2 只有前 a 步走的路徑不同,所以當 p1 和 p2 再次重合的時候,必然是在鍊錶的環路入口點上。
6. 判斷兩個鍊錶是否相交(鍊錶無環)
題目描述:給出兩個單向鍊錶的頭指標,判斷這個鍊錶是否相交。
解法:我們可以像,如果兩個鍊錶相交於某一點,那麼在這個節點之後的所有節點都是兩個鍊錶所共有的節點。此時我們就可以知道如果兩個鍊錶相交,則他們最後乙個節點一定是共有的。這樣我們就不難想出解題思路了。
先遍歷第乙個鍊錶,記住最後乙個節點,然後再遍歷第二個鍊錶,到最後乙個節點時與第乙個鍊錶的最後乙個節點作比較,如果相等,則說明這兩條鍊錶相交,否則不相交。
7. 鍊錶有環,如何判斷相交
解法:如果有環且兩個鍊錶相交,則兩個鍊錶都有共同乙個環,即環上的任意乙個節點都存在於兩個鍊錶上。因此,就可以判斷一煉表上倆指標相遇的那個節點,在不在另一條鍊錶上即可。
8. 兩鍊錶相交的第乙個公共節點
題目描述:如果兩個無環單鏈表相交,怎麼求出它們相交的第乙個節點呢?
解法:計算兩個鍊錶的長度 l1,l2,分別用兩個指標 p1、p2 指向兩個鍊錶的頭,然後將較長鍊錶的 p1(假設為 p1)向後移動l2 - l1 個節點,然後再同時向後移動 p1、p2,直到 p1 = p2。相遇的節點就是相交的第乙個節點。
總結:我們可以發現,在鍊錶有關的問題中,兩個指標是十分值得我們考慮的提高效率的解決方案。
鍊錶中環問題詳解
這個問題在面試中是老生常談的問題了,而且,解決這類問題的主要方法就是追擊法,因此,這篇部落格中只講解這種方法求解環的問題。這裡給出三個鍊錶中環的問題 這裡給出一副,所有的討論都在這上進行。這個問題很好解決,設定兩個指標ptr 1,ptr 2在a處,讓ptr 1以1的速度往後走 即每次移動乙個位置 p...
Linux中的核心鍊錶例項詳解
linux中的核心鍊錶例項詳解 鍊錶中一般都要進行初始化 插入 刪除 顯示 釋放鍊錶,尋找節點這幾個操作,下面我對這幾個操作進行簡單的介紹,因為我的能力不足,可能有些東西理解的不夠深入,造成一定的錯誤,請各位博友指出。a linux核心鍊錶中的幾個主要函式 下面是核心中的原始碼拿出來給大家分析一下 ...
雙向鍊錶例項
package com.wyl.linklist 雙向鍊錶,實現26個字母的迴圈輸出 author wyl public class mybinarylink public node char data public node char data,node prior,node next publi...