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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[剑指offer]面试题15:链表中倒数第k个结点

發布時間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [剑指offer]面试题15:链表中倒数第k个结点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

面試題15:鏈表中倒數第k個結點
題目:輸入一個鏈表,輸出該鏈表中倒數第 k 個結點。為了符合大多數人的習慣,本題從1 開始計數,即鏈表的尾結點是倒數第1 個結點。例如一個鏈表有6個結點,從頭結點開始它們的值依次是1、2、3、4、5、6。這個鏈表的倒數第3個結點是值為4的結點。
鏈表結點定義如下:

struct ListNode {int value;ListNode *next; };

為了實現只遍歷鏈表一次就能找到倒數第 k 個結點,我們可以定義兩個指針。
第一個指針從鏈表的頭指針開始遍歷向前走k-1,第二個指針保持不動;
從第 k 步開始,第二個指針也開始從鏈表的頭指針開始遍歷。
由于兩個指針的距離保持在k-1,當第一個(走在前面的)指針到達鏈表的尾結點時,第二個指針(走在后面的)指針正好是倒數第k個結點。

代碼如下:

ListNode *FindKthToTail(ListNode *pListHead, unsigned int k) {ListNode *pAhead = pListHead;ListNode *pBehind = nullptr;for (unsigned int i = 0; i < k - 1; i++){pAhead = pAhead->next;}pBehind = pListHead;while (pAhead->next != nullptr){pAhead = pAhead->next;pBehind = pBehind->next;}return pBehind; }

以上面的代碼為例,面試官可以找出3種辦法讓這段代碼崩潰:

  • 輸入的pListHead為空指針。由于代碼會試圖訪問空指針指向的內存,程序崩潰。
  • 輸入的以pListHead為頭結點的鏈表的結點總數少于k。由于在for循環中會在鏈表上向前走k-1步,仍然會由于空指針造成程序崩潰。
  • 輸入的參數k為0。由于k是一個無符號整數,那么在for循環中k-1得到的將不是-1,而是4294967295(無符號的0xFFFFFFFF)。因此for循環執行的次數遠遠超出我們的預計,同樣也會造成程序崩潰。
  • 寫代碼要特別注意魯棒性。

    針對前面指出的 3 個問題,我們要分別處理。

  • 如果輸入的鏈表頭指針為 NULL,那么整個鏈表為空,此時查找倒數第 k 個結點自然應該返回NULL。
  • 如果輸入的k是0,也就是試圖查找倒數第0個結點,由于我們計數是從1 開始的,因此輸入0 沒有實際意義,也可以返回NULL。
  • 如果鏈表的結點數少于 k,在 for 循環中遍歷鏈表可能會出現指向 NULL的m_pNext,因此我們在for循環中應該加一個if判斷。
  • 修改之后的代碼如下:

    ListNode *FindKthToTail(ListNode *pListHead, unsigned int k) {if (pListHead == nullptr || k == 0) return nullptr;ListNode *pAhead = pListHead;ListNode *pBehind = nullptr;for (unsigned int i = 0; i < k - 1; i++){if (pAhead->next != nullptr){pAhead = pAhead->next;}else return nullptr;}pBehind = pListHead;while (pAhead->next != nullptr){pAhead = pAhead->next;pBehind = pBehind->next;}return pBehind; }

    測試用例:
    ● 功能測試(第k 個結點在鏈表的中間,第k 個結點是鏈表的頭結點,第k個結點是鏈表的尾結點)。
    ● 特殊輸入測試(鏈表頭結點為 NULL 指針,鏈表的結點總數少于k,k等于0)。
    本題考點:
    ● 考查對鏈表的理解。
    ● 考查代碼的魯棒性。魯棒性是解決這道題的關鍵所在。如果應聘者寫出的代碼有著多處崩潰的潛在風險,那么他是很難通過這輪面試的。
    相關題目:
    ● 求鏈表的中間結點。如果鏈表中結點總數為奇數,返回中間結點;如果結點總數是偶數,返回中間兩個結點的任意一個。為了解決這個問題,我們也可以定義兩個指針,同時從鏈表的頭結點出發,一個指針一次走一步,另一個指針一次走兩步。當走得快的指針走到鏈表的末尾時,走得慢的指針正好在鏈表的中間。
    ● 判斷一個單向鏈表是否形成了環形結構。和前面的問題一樣,定義兩個指針,同時從鏈表的頭結點出發,一個指針一次走一步,另一個指針一次走兩步。如果走得快的指針追上了走得慢的指針,那么鏈表就是環形鏈表;如果走得快的指針走到了鏈表的末尾(m_pNext指向NULL)都沒有追上第一個指針,那么鏈表就不是環形鏈表。

    總結

    以上是生活随笔為你收集整理的[剑指offer]面试题15:链表中倒数第k个结点的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。