劍指Offer15 列印單鏈表倒數第k個節點

2021-09-26 15:15:39 字數 1162 閱讀 2868

輸入乙個鍊錶,輸出該鍊錶中倒數第k個節點。注意鍊錶結點計數從1開始,即鍊錶的尾結點是倒數第1個結點。例如乙個鍊錶有6個結點,從頭開始它們的值依次為1、2、3、4、5、6。這個鍊錶的倒數第3個結點是值為4的結點。

由於是單鏈表所以,要想找到倒數第k個結點,首先得知道鍊錶長度,進行一次遍歷得到鍊錶的長度length,然後用length-k+1即得到需要遍歷輸出的結點位置進行第二次遍歷,輸出第length-k+1個結點的值。但是如此一來就要進行兩次遍歷了,時間複雜度上太高;如何在一次遍歷的情況下輸出結果呢?

雙指標法:定義兩個指標,乙個快,乙個慢;快的指標比慢的指標快k個結點;然後兩個指標同時開始遍歷,當快的指標指向尾結點時,慢的指標將指向倒數第k個結點。但是在此過程中需要注意判斷輸入的k是否合法(不能為0;不能超過鍊錶的長度)

1、求鍊錶的中間結點。如果鍊錶中結點總數為奇數,返回中間結點;如果結點總數是偶數,返回中間兩個結點的任意乙個。為了解決這個問題,我們也可以定義兩個指標,同時從鍊錶的頭結點出發,乙個指標一次走一步,另乙個指標一次走兩步。當走得快的指標走到鍊錶的末尾時,走得慢的指標正好在鍊錶的中間。

2、判斷乙個單鏈表是否形成了環形結構。定義兩個指標,同時從鍊錶的頭結點出發,乙個指標一次走一步,另乙個指標一次走兩步。如果走得快的指標追上了走得慢的指標,那麼鍊錶就是環形鍊錶;如果走得快的指標走到了鍊錶的末尾(.next==null)都沒有追上第乙個指標,那麼鍊錶就不是環形鍊錶。

public class code015 

private static listnode findkthtotail(listnode plisthead, int k)

listnode pfast=plisthead;

listnode pslow=null;

//因為是從1開始計數;因此快指標應該是比慢指標快k-1個結點

for(int i=0;i}

//定義慢指標初始指向頭結點

pslow=plisthead;

//開始遍歷,遍歷結束條件為快指標指向鍊錶的尾(即快指標的下乙個結點指向null)

while (pfast.next!=null)

return pslow;

}private static class listnode

public listnode(int value)

}}

劍指offer全套解答 劍指offer 1 5

1.二維陣列中的查詢 在乙個二維陣列中 每個一維陣列的長度相同 每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。public class solution int n array 0 length i...

劍指offer 3 列印鍊錶

輸入乙個鍊錶,按煉錶值從尾到頭的順序返回乙個arraylist 利用棧具有先進後出的陣列組合特性,將資料壓入棧中,然後將棧中的資料壓入vector中,便組成了乙個arraylist include include include using namespace std using std vecto...

劍指offer 15 反轉鍊錶

輸入乙個鍊錶,反轉鍊錶後,輸出鍊錶的所有元素。反轉鍊錶只需改變鏈結方向,改變方向時需要將原本指向後乙個結點的鏈結方向指向前乙個結點,因此需要記錄下三個結點。include using namespace std struct listnode class solution listnode fron...