題目描述
輸入一個鏈表,輸出該鏈表中倒數第k個結點。爲了符合大多數人的習慣,本題從1開始計數,即鏈表的尾結點是倒數第1個結點。例如一個鏈表中有6個結點,從頭結點開始它們的值依次是1,2,3,4,5,6.這個鏈表的倒數第3個結點是值爲4的結點。
解析
假設整個鏈表有n個結點,那麼倒數第k個結點就是從頭結點開始的第n-k個結點.需要兩次遍歷鏈表,第一次統計鏈表的中的結點個數,第二次就能找到鏈表的倒數第k個結點。時間複雜度爲O(n^2).
如何實現只遍歷鏈表一次就找到倒數第k個結點?利用兩個指針,第一個指針從鏈表的頭指針開始遍歷向前走k-1步,第二個指針保持不動,從第k步開始,兩個指針一起向後走。兩個指針的距離保持在k-1,當第一個指針到達鏈表的尾結點時,第二個指針正好是倒數第k個結點。
注意:
需要判斷傳參有效性
當第一指針向前走k-1步的時候,要注意,不確定鏈表結點數是否大於k,需要每一步都判斷是否到達鏈表結尾,並作出相應的輸出。
實現
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){
if (pListHead == NULL || k <= 0)
return NULL;
ListNode* pAhead = pListHead;
ListNode* pBehind = pListHead;
for (int i = 0; i < k-1; i++){
if (pAhead->m_pNext != NULL){ //因爲不知道鏈表結點數是否大於k
pAhead = pAhead->m_pNext;
}
else{
return NULL;
}
}
while (pAhead->m_pNext != NULL){
pAhead = pAhead->m_pNext;
pBehind = pBehind->m_pNext;
}
return pBehind;
}
拓展
1. 求鏈表的中間結點.
快慢指針。
2. 判斷一個單向鏈表是否形成了一個環形結構.
用快慢指針,如果慢的指針追上快指針了,有環結構存在。如果快指針遍歷到NULL了,則沒有環結構存在。