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