為了實現只遍歷鍊錶⼀次就能找到倒數第k個結點, 我們可以定義兩個指標,初始化均指向頭結點。
第⼀個指標 p1從鍊錶的頭指標開始遍歷向前⾛ k-1 步, 第⼆個指標 p2保持不動;
從第k步開始, 第⼆個指標也開始從鍊錶的頭指標開始遍歷,即雙指標共同移動;
由於兩個指標的距離保持在 k-1, 當第⼀個(⾛在前⾯的) 指標到達鍊錶的尾結點時, 第⼆個指標(⾛在後⾯的) 指標與尾結點的距離為 k-1,正好是倒數第k個結點。
考慮到**的魯棒性,還需要對一些特殊情況進行處理:
/**
* definition for singly-linked list.
* public class listnode
* }*/class
solution
// 走完 k步後,此時兩個指標距離為 k-1,
// 接下來共同移動,直到快指標到達鍊錶尾結點時,此時慢指標與尾結點距離為 k-1,正好為倒數第 k個結點
while
(p1.next != null)
return p2;
}}
簡化**,通過乙個輔助變數 t 代替第乙個 for 迴圈
class
solution
if(p1 == null && t
return null;
// 鍊錶長度小於 k
return p2;
}}
時間複雜度:o(n),快指標遍歷了整個鍊錶,走了 n步,慢指標走了 n-k 步。
空間複雜度:o(1),雙指標只需要常數大小的額外空間。
面試題15 鍊錶中倒數第k個節點
題目 輸入乙個鍊錶,輸出該鍊錶中倒數第k個節點。從1開始計數,如鍊表有1,2,3,4,5,6.倒數第三個節點是值為4的節點。可以採用兩個指標,思路比較清晰,但是就是一些邊界條件很難考慮全,比如k超出了鍊錶的長度。struct listnode class solution if fast null ...
面試題15 鍊錶中倒數第K個節點
鍊錶的定義如下 struct listnode 有三種方法 遞迴法,自定義棧法和前後指標法。如下 listnode findkthtotail listnode head,int k else if k 1 else if k 1 k listnode findkthtotail listnode ...
面試題22 鍊錶中倒數第k個節點
假如單鏈表有n個節點,倒數第k個節點,即為n k 1 利用雙指標進行判斷,前指標走到k 1的位置,即開頭的k 1位置,然後讓後指標跟前指標一起走 當前指標到達尾部的時候,後指標剛好到達倒數第k個節點 include struct listnode 假如單鏈表有n個節點,倒數第k個節點,即為n k 1...