輸入乙個鍊錶,輸出該鍊錶中倒數第k個節點。為了符合大多數人的習慣,本題從1開始計數,即鍊錶的尾節點是倒數第1個節點。
例如,乙個鍊錶有6個節點,從頭節點開始,它們的值依次是1、2、3、4、5、6。這個鍊錶的倒數第3個節點是值為4的節點。
示例:
給定乙個鍊錶: 1->2->3->4->5, 和 k = 2.雙指標求解這題要求鍊錶的倒數第k個節點,最簡單的方式就是使用兩個指標,第乙個指標先移動k步,然後第二個指標再從頭開始,這個時候這兩個指標同時移動,當第乙個指標到鍊錶的末尾的時候,返回第二個指標即可。返回鍊錶 4->5.
public listnode getkthfromend
(listnode head,
int k)
//然後兩個指標在同時前進
while
(first != null)
return second;
}
使用棧解決這題要求的是返回後面的k個節點,我們只要把原鍊錶的結點全部壓棧,然後再把棧中最上面的k個節點出棧,出棧的結點重新串成乙個新的鍊錶即可,原理也比較簡單,直接看下**。
public listnode getkthfromend
(listnode head,
int k)
//在出棧串成新的鍊錶
listnode firstnode = stack.
pop();
while
(--k >0)
return firstnode;
}
遞迴求解我們之前講過鍊錶的逆序列印410,劍指 offer-從尾到頭列印鍊錶,其中有這樣一段**
public
void
reverseprint
(listnode head)
這段**其實很簡單,我們要理解他就要弄懂遞迴的原理,遞迴分為兩個過程,遞和歸,看一下下面的圖就知道了,先往下傳遞,當遇到終止條件的時候開始往回走。
前面也剛講過遞迴的原理426,什麼是遞迴,通過這篇文章,讓你徹底搞懂遞迴,這題如果使用遞迴的話,我們先來看一下遞迴的模板
public listnode getkthfromend
(listnode head,
int k)
終止條件很明顯就是當節點head為空的時候,就沒法遞迴了,這裡主要看的是邏輯處理部分,當遞迴往下傳遞到最底端的時候,就會觸底**往回走,在往回走的過程中記錄下走過的節點,當達到k的時候,說明到達的那個節點就是倒數第k個節點,直接返回即可,如果沒有達到k,就返回空,搞懂了上面的過程,**就很容易寫了
//全域性變數,記錄遞迴往回走的時候訪問的結點數量
int size;
public listnode getkthfromend
(listnode head,
int k)
else
if(size == k)
else
}
上面**在仔細一看,當size小於k的時候node節點就是空,所以我們可以把size大於k和小於k合併為乙個,這樣**會更簡潔一些
int size;
public listnode getkthfromend
(listnode head,
int k)
總結這題最簡單的估計就是第一種使用雙指標的方式了,關於鍊錶的知識也可以看下前面講的352,資料結構-2,鍊錶
劍指offer 鍊錶中倒數第k個結點(鍊錶)
輸入乙個鍊錶,輸出該鍊錶中倒數第k個結點。分析 兩個指標pointresult和pointend一起指向頭結點,然後根據k,移動pointend,使pointresult和pointend的距離為k 1。然後同時移動pointresult和pointend,當pointend指向最後乙個結點時,po...
劍指offer 鍊錶
單向鍊錶的結構定義 typedef int datatype struct listnode 問題1 往鍊錶的末尾新增乙個結點 給定頭結點,往末尾插入乙個結點 void insertnode listnode head,datatype key listnode p head while p nex...
劍指offer 鍊錶
鍊錶 鍊錶是一種動態資料結構 struct listnode 往鍊錶的末尾新增乙個節點的c 程式如下 void addtotail listnode phead,int value 注意第乙個引數phead是乙個指向指標的指標。當我們往乙個空鍊錶插入乙個結點時,else pnode m pnext ...