一、題目
輸入乙個鍊錶,輸出該鍊錶中倒數第k個結點。為了符合大多數人的習慣,本題從1開始計數,即鍊錶的尾結點是倒數第1個結點。例如乙個鍊錶有6個結點,從頭結點開始它們的值依次是1、2、3、4、5、6。這個鍊錶的倒數第3個結點是值為4的結點。
二、關鍵
1.兩個指標的思想。
2.三個魯棒性問題。(1)輸入的鍊錶是空指標。(2)鍊錶的節點個數小於k。(3)輸入的引數小於等於0.
三、解釋
1.思路一:倒數第k個節點就是第n-k+1個節點。我們從頭開始遍歷一遍鍊錶,每經過乙個節點,計數器加1,統計出鍊錶的個數。第二遍,我們從頭到尾遍歷,找到第n-k+1個節點,就能得到倒數第k個節點。
2.思路二:只遍歷一次就得到倒數第k個節點。方法:定義兩個指標,第乙個指標從鍊錶的頭部開始遍歷,第二個指標不動。當第乙個指標走了k-1步後,第二個指標也開始從頭開始遍歷。由於兩個 指標的距離保持在k-1,所以,當第乙個指標走到了鍊錶的尾部的時候,第二個指標剛好走到了倒數第k個節點。
3.相關題目:求鍊錶的中間節點。如果鍊錶中的節點總數為奇數,則返回中間節點;如果節點總數是偶數,則返回中間兩個節點的任意乙個。解決方法:定義兩個指標,同時從鍊錶的頭節點出發,乙個指標一次走一步,另乙個指標一次走兩步。當走得快的指標走到鍊錶的末尾時,走得慢的指標剛好在鍊錶的中間。
4.舉一反三:當我們使用乙個指標遍歷鍊錶不能解決的時候,可以嘗試使用兩個指標來遍歷鍊錶。可以讓其中乙個指標走的快,或者讓它先走若干步。
四、**
#include #include "..\utilities\list.h"
listnode* findkthtotail(listnode* plisthead, unsigned int k)
}pbehind = plisthead;
while(pahead->m_pnext != nullptr)
return pbehind;
}// ********************測試**********************
// 測試要找的結點在鍊錶中間
void test1()
// 測試要找的結點是鍊錶的尾結點
void test2()
// 測試要找的結點是鍊錶的頭結點
void test3()
// 測試空鍊錶
void test4()
// 測試輸入的第二個引數大於鍊錶的結點總數
void test5()
// 測試輸入的第二個引數為0
void test6()
int main(int argc, char* argv)
面試題22 鍊錶中倒數第k個結點
輸入乙個鍊錶,輸出該鍊錶中倒數第k個結點。如果是雙向鍊錶,可以遍歷到最後乙個,再通過prev指標找到倒數第k個。如果是單向鍊錶,訪問倒數第k個,需要遍歷n k 1個結點,但是獲取n的時候,需要遍歷一遍鍊錶,這不是最佳的解決方案。為了實現只遍歷鍊錶一次就能找到倒數第k個結點,我們可以定義兩個指標,第乙...
面試題22 鍊錶中倒數第K個結點
輸入乙個鍊錶,輸出該鍊錶中倒數第k個節點。為了符合大多數人的習慣,本題從1開始計數,即鍊錶的尾節點是倒數第1個節點。例如,乙個鍊錶有6個節點,從頭節點開始,它們的值依次是1 2 3 4 5 6。這個鍊錶的倒數第3個節點是值為4的節點。思路 雙指標法,第乙個指標 first 先走 k 步,第二個指標 ...
面試題22 鍊錶中倒數第k個節點
假如單鏈表有n個節點,倒數第k個節點,即為n k 1 利用雙指標進行判斷,前指標走到k 1的位置,即開頭的k 1位置,然後讓後指標跟前指標一起走 當前指標到達尾部的時候,後指標剛好到達倒數第k個節點 include struct listnode 假如單鏈表有n個節點,倒數第k個節點,即為n k 1...