這幾天把劍指offer題庫中的鍊錶題刷了一遍,總結了下鍊錶題常見的解法思路。
對每個常見的解法舉典型例子展示下。
雙指標法
劍指offer22 鍊錶中倒數第k個節點該題最簡單的方法時先遍歷一遍計算下節點數,在遍歷到倒數第k個節點輸出後序節點。輸入乙個鍊錶,輸出該鍊錶中倒數第k個節點。為了符合大多數人的習慣,本題從1開始計數,即鍊錶的尾節點是倒數第1個節點。例如,乙個鍊錶有6個節點,從頭節點開始,它們的值依次是1、2、3、4、5、6。這個鍊錶的倒數第3個節點是值為4的節點。
示例:給定乙個鍊錶: 1->2->3->4->5, 和 k = 2.
返回鍊錶 4->5.
而雙指標解法的思想在於,雖然我們不知道節點總數但我們知道需要輸出的節點數目,我們可以使用前後兩個相差k-1的指標同時向後遍歷,當前指標到達尾節點時,後節點剛好到達倒數第k個節點。
class solution
return list2;}}
;
遞迴法劍指offer24 反轉鍊錶反轉鍊錶這種需要先處理後面的問題很自然的就想到能不能使用遞迴方法。定義乙個函式,輸入乙個鍊錶的頭節點,反轉該鍊錶並輸出反轉後鍊錶的頭節點。
示例:輸入: 1->2->3->4->5->null
輸出: 5->4->3->2->1->null
限制:0 <= 節點個數 <= 5000
class solution
};
此**中重點語句是head->next->next = head;
具體分析可以檢視
迭代法迭代法就是利用鍊錶的鏈式結構一步一步向後迭代實現所要求的內容。
劍指offer 25 合併兩個排序的鍊錶輸入兩個遞增排序的鍊錶,合併這兩個鍊錶並使新鍊錶中的節點仍然是遞增排序的。
示例1:
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
限制:0 <= 鍊錶長度 <= 1000
class solution
//加入節點l2
else
cur = cur->next;
}//加入剩餘節點
cur->next = l1 ==
null
? l2 : l1;
return dummy->next;}}
;
利用棧、map、vector、雜湊表等資料結構的方法。
根據棧先進後出,雜湊表的雜湊對映,map的鍵值對等等特點可以很好的解決一些特定問題。
劍指offer 35 複雜鍊錶的複製本題涉及到鍊錶的深拷貝,比較麻煩的是random指標的存在。此時就可以使用map這種資料結構來幫助我們是實現拷貝。
c++中有三種型別的map:
對映底層實現
是否有序
數值是否可以重複
能否更改數值
查詢效率
增刪效率
std::map
紅黑樹key有序
key不可重複
key不可修改
o(logn)
o(logn)
std::multimap
紅黑樹key有序
key可重複
key不可修改
o(logn)
o(logn)
std::unordered_map
雜湊表key無序
key不可重複
key不可修改
o(1)
o(1)
因為我們主要是查詢next、random節點,所以我們用底層是雜湊表實現的unordered_map。
class solution
list = head;
while
(list !=
null)if
(list->random)
list = list->next;
}return map[head];}
};
unordered_mapmap,實現的是複製與深拷貝後節點的一一對應。
剛開始的深拷貝,將原先的節點深拷貝後的兒子放入map與其父親一一對應
map[list]=new node(list->val);
next與random指標的複製對應關係:
map[list]->next=map[list->next];
map[list]->random=map[list->random];
此問題除了利用map來實現外,還有乙個很巧妙地方法
拆分法
class solution
void
copynodes
(node *head)
}void
connectrandomnode
(node *head)
node = copynode->next;}}
node *
splitcopynodelist
(node *head)
return copyhead;}}
;
這個題解裡有描述拆分法的詳細的**。
鍊錶題一般都是比較簡單的題,使用的方法也無外乎上述的方法。一刷總結。
力扣206 劍指offer24 反轉鍊錶 C
定義乙個函式,輸入乙個鍊錶的頭節點,反轉該鍊錶並輸出反轉後鍊錶的頭節點。示例 輸入 1 2 3 4 5 null 輸出 5 4 3 2 1 null 限制 0 節點個數 5000 題目 本題考察的知識點就是鍊錶的反轉。看到題目想到的解法就是雙指標。class solution return cur ...
劍指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 ...