面试题整理 2:求链表倒数第 k 个结点
生活随笔
收集整理的這篇文章主要介紹了
面试题整理 2:求链表倒数第 k 个结点
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
注意問題:想好思路,注意空指針問題;當(dāng)節(jié)點數(shù)<k時;當(dāng)k=0時;邊界的處理問題。 注意輸入?yún)?shù)鏈表頭指針是指向指針的指針。
ListNode* FindKthToTail(ListNode** pListHead, unsigned int k) { if( pListHead == NULL || *pListHead == NULL || k == 0 ) return NULL; ListNode *pAhead = *pListHead; ListNode *pBehind = NULL; for(unsigned int i = 0; i < k - 1; ++ i) { pAhead = pAhead->m_pNext; if(pAhead == NULL) return NULL; } pBehind = *pListHead; while(pAhead->m_pNext != NULL) { pAhead = pAhead->m_pNext; pBehind = pBehind->m_pNext; } return pBehind; }
題目:輸入一個單向鏈表,輸出該鏈表中倒數(shù)第 k 個結(jié)點。鏈表的倒數(shù)第 0 個結(jié)點為鏈表的尾指針。?
鏈表結(jié)點定義如下: ?
struct ListNode { int m_nKey; ListNode* m_pNext; };分析:為了得到倒數(shù)第 k 個結(jié)點,很自然的想法是先走到鏈表的尾端,再從尾端回溯 k 步。可是輸入的是單向鏈表,只有從前往后的指針而沒有從后往前的指針,怎么辦?
(1)假設(shè)整個鏈表有 n個結(jié)點,那么倒數(shù)第 k 個結(jié)點是從頭結(jié)點開始的第 n-k-1 個結(jié)點(從 0 開始計數(shù))。如果我們能夠得到鏈表中結(jié)點的個數(shù) n,那我們只要從頭結(jié)點開始往后走 n-k-1 步就可以了。如何得到結(jié)點數(shù) n?只需要從頭開始遍歷鏈表,每經(jīng)過一個結(jié)點,計數(shù)器加一就行了。??
這種思路的時間復(fù)雜度是 O(n),但需要遍歷鏈表兩次。第一次得到鏈表中結(jié)點個數(shù) n,第二次得到從頭結(jié)點開始的第 n-k-1 個結(jié)點即倒數(shù)第 k 個結(jié)點。?
如果鏈表的結(jié)點數(shù)不多,這是一種很好的方法。但如果輸入的鏈表的結(jié)點個數(shù)很多,有可能不能一次性把整個鏈表都從硬盤讀入物理內(nèi)存,那么遍歷兩遍意味著一個結(jié)點需要兩次從硬盤讀入到物理內(nèi)存。我們知道把數(shù)據(jù)從硬盤讀入到內(nèi)存是非常耗時間的操作。我們能不能把鏈表遍歷的次數(shù)減少到 1?如果可以,將能有效地提高代碼執(zhí)行的時間效率。 (2)如果我們在遍歷時維持兩個指針,第一個指針從鏈表的頭指針開始遍歷,在第 k-1步之前,第二個指針保持不動;在第 k-1 步開始,第二個指針也開始從鏈表的頭指針開始遍歷。由于兩個指針的距離保持在 k-1,當(dāng)?shù)谝粋€(走在前面的)指針到達(dá)鏈表的尾結(jié)點時,第二個指針(走在后面的)指針正好是倒數(shù)第 k 個結(jié)點。? 這種思路只需要遍歷鏈表一次。對于很長的鏈表,只需要把每個結(jié)點從硬盤導(dǎo)入到內(nèi)存一次。因此這一方法的時間效率前面的方法要高。?注意問題:想好思路,注意空指針問題;當(dāng)節(jié)點數(shù)<k時;當(dāng)k=0時;邊界的處理問題。 注意輸入?yún)?shù)鏈表頭指針是指向指針的指針。
ListNode* FindKthToTail(ListNode** pListHead, unsigned int k) { if( pListHead == NULL || *pListHead == NULL || k == 0 ) return NULL; ListNode *pAhead = *pListHead; ListNode *pBehind = NULL; for(unsigned int i = 0; i < k - 1; ++ i) { pAhead = pAhead->m_pNext; if(pAhead == NULL) return NULL; } pBehind = *pListHead; while(pAhead->m_pNext != NULL) { pAhead = pAhead->m_pNext; pBehind = pBehind->m_pNext; } return pBehind; }
總結(jié)
以上是生活随笔為你收集整理的面试题整理 2:求链表倒数第 k 个结点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《深度探索C++对象模型》--5 构造析
- 下一篇: 面试题整理3 大数的表示及加减法问题