15. 鏈表中倒數第k個結點

題目描述

輸入一個鏈表,輸出該鏈表中倒數第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了,則沒有環結構存在。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章