劍指offer之鍊錶 鍊錶型別所有題總結

2021-10-10 15:04:05 字數 3429 閱讀 2810

劍指 offer 22 鍊錶中倒數第k個節點

劍指 offer 24 反轉鍊錶

劍指 offer 18 刪除鍊錶的節點

劍指 offer 35 複製鍊錶的複製

劍指 offer 52 兩個鍊錶的第乙個公共節點

本篇文章記錄劍指offer標籤為鍊錶的題。

下面的題都是在力扣上面做的,可以按照題名搜尋即可

將鍊錶的元素記錄到陣列中,反轉返回即可。

時間複雜度o(n),空間複雜度o(1)

我們把鍊錶的最後乙個節點的null看成乙個節點,那麼我們可以發現倒數第k個節點和這個null之間的距離(邊)即是k。

利用上述的性質,我們可以用兩個指標,維護這段距離,乙個指標指向開頭,另外乙個指標先走k步,然後兩個指標同時往後走,當先走的指標到達了null域的時候,第乙個指標所指向的節點就是倒數第k個節點。

時間複雜度o(n)

我們用兩個指標,改變每個指標的指向即可,同時向後走,如上圖,如果b走到null時候,說明鍊錶反轉完畢,此時a所指的節點就是反轉後鍊錶的第乙個節點。

注意:需要特判空鍊錶,並且要在一開始將a的next設為空

時間複雜度o(n)

因為是單鏈表,我們如果找到了要被刪除的節點,還需要知道該節點的前驅才行。

為了方便刪除操作,我們用乙個虛擬頭節點加在單鏈表的前面,遍歷鍊錶時候,我們需要要探測該節點下乙個節點的值,如果該節點下乙個節點就是我們需要刪除的節點,改變該節點的指向即可。

注意:邊界問題是要刪除的元素是鍊錶的最後乙個元素,為了防止空指標異常,我們刪除元素後break掉

時間複雜度o(n)

因為要深拷貝,所以我們可以用雜湊表來將兩個鍊錶的每個節點進行對映,那這樣空間複雜度是o(n)。我們發現了另外一種方法:

在該題中最關鍵的是拷貝random域。可以用如下的方法

紅色的節點是我們拷貝的節點。

1.先將原鍊錶的每個節點後面拷貝乙個節點。

2.根據原鍊錶的random域設定複製鍊錶的random

3.將複製的鍊錶抽出。

時間複雜度o(n),空間複雜度o(1)

注意:需要特判random是否為空,否則會產生空指標異常

/*

// definition for a node.

class node

};*/

class

solution

//複製random域

for(

auto p = head ; p;

)//將已經有的鍊錶抽出

根據樣例,我們發現答案有以下兩種情況。

1.有相交節點

具體的實現:q和p一直往後走,如果q走完了,q再從p鍊錶開頭走,如果p走完了,p再從q鍊錶開頭走,這樣第二次他們就會在公共點相遇。

為什麼上面這樣的做法是正確的呢?

如果按照這樣的策略,q走過的距離是a + c + b,而p走過的距離是b + c + a,所以上述的做法一定是正確的。

2.無相交節點

其實這樣的情況我們可以看成p和q鍊錶的公共節點是null,按照上面的策略,p走過的距離是a + b,而q走過的距離是b + a,那麼他們會在null相遇。

時間複雜度o(n),空間複雜度o(1)

/**

* definition for singly-linked list.

* struct listnode

* };

*/class

solution

return q;}}

;

劍指Offer 鍊錶 反轉鍊錶

定義乙個函式,輸入乙個鍊錶的頭節點,反轉該鍊錶並輸出反轉後鍊錶的頭節點。解題思路 演算法流程 複雜度分析 實現 class solution object defreverselist self,head 申請兩個節點,pre和cur,pre最初指向none pre none cur head 遍歷...

劍指offer 鍊錶

單向鍊錶的結構定義 typedef int datatype struct listnode 問題1 往鍊錶的末尾新增乙個結點 給定頭結點,往末尾插入乙個結點 void insertnode listnode head,datatype key listnode p head while p nex...

劍指offer 鍊錶

鍊錶 鍊錶是一種動態資料結構 struct listnode 往鍊錶的末尾新增乙個節點的c 程式如下 void addtotail listnode phead,int value 注意第乙個引數phead是乙個指向指標的指標。當我們往乙個空鍊錶插入乙個結點時,else pnode m pnext ...