日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试题整理 2:求链表倒数第 k 个结点

發(fā)布時間:2025/3/21 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试题整理 2:求链表倒数第 k 个结点 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


題目:輸入一個單向鏈表,輸出該鏈表中倒數(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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。