輸入乙個鍊錶,輸出該鍊錶中倒數第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...