玩轉演算法面試之連結串列
206 Reverse Linked List
- 反轉連結串列。
- 一般遇到這種題,入門的大概思路是利用棧儲存,然後再反向彈出賦值更新(改變連結串列中的值),不過這種思路是錯誤的。
- 那我先把頭結點指向Null? 錯,因為這樣我們就拿不到2這個節點了。
- 我們需要三個指標來幫我們解決問題。(pre,cur,next)三個節點依次向前移動
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
let pre = null
while (head) {
// 儲存下一個結點
next = head.next
// 反轉指標方向
head.next = pre
// 節點遞增
pre = head
head = next
}
return pre
};
92. Reverse Linked List II
反轉一個連結串列從m到n的元素。
如對於連結串列1->2->3->4->5->NULL,m=2,n=4。則返回連結串列1->4->3->2->5->NULL
- m和n超過連結串列範圍怎麼辦? m和n是負值怎麼辦?
- m>n怎麼辦?
- m=1.或者n是最後一個
var reverseBetween = function(head, m, n) {
if(m >= n) {
return head;
}
var dummy = new ListNode(0); //透過構建listNode,處理m==1的情況
dummy.next = head;
head = dummy;
// 移動head到m-1的node;
for(var i = 0; i
83. Remove Duplicates from Sorted List
給出一個有序連結串列,刪除其中所有重複元素,使得每個元素只保留一次。
- 如1->1->2,返回1->2
- 如1->1->2->3->3,返回1->2->3
86. Partition List
給出一個連結串列以及一個數x,將連結串列重新整理,使得小於x的元素在前;大於等於x的元素在後。
- 如1->4->3->2->5->2,×=3
- 返回1->2->2->4->3->5
- 左邊和右邊的順序是任意還是需要保持原有連結串列的順序
328. Odd Even Linked List
給出一個連結串列,將連結串列重新整理,使得所有索引為奇數的節點排在索引為偶數的節點前面。
- 如1->2->3->4->5->NULL
- 返回1->3->5->2->4->NULL
- 第一個節點的索引為1
- 奇數索引的節點和偶數索引的節點在重新整理後要保持相對順序。
2. Add Two Numbers
給出兩個非空連結串列,表示兩個非負整數。其中每一個整數的各位數字以逆序儲存,返回這兩個整數相加所代表的連結串列。
- 如342+465=807
- 則給出2->4->3和5->6->4,返回7->0->8
- 數字中是否有前置的零。(除零以外,沒有前置零)
- 當我們遇到字串表示數字的情況時,要考慮負數。本文因為已經支援非負整數
445. Add Two Numbers II
給出兩個非空連結串列,表示兩個非負整數。其中每一個整數的各位數字以順序儲存,返回這兩個整數相加所代表的連結串列。
- 如342+465=807
- 則給出3->4->2和4->6->5,返回8->0->7
- 不允許修改輸入的連結串列
- 使用輔助資料結構
設立連結串列的虛擬頭節點
203. Remove Linked List Elements
在連結串列中刪除值為val的所有節點
- 如1->2->6->3->4->5->6->NULL,要求刪除值為6的節點
- 返回1->2->3->4->5->NULL
-
對刪除第一個元素不適用,不過我們可以拿出來單獨判斷頭節點,但是這樣就產生了兩個刪除邏輯,所以這個時候就需要dummy虛擬節點,這樣對連結串列中的所有節點都可以統一了
var removeElements = function(head, val) {
if(head === null){
return head;
}
var dummy = new ListNode(-1);
dummy.next = head;
prev = dummy;
cur = head;
while(prev !== null && prev.next !== null){
// 如果當前元素等於要刪除元素,刪除
if(cur.val === val) {
prev.next = cur.next;
cur = prev.next;
} else {
prev = cur;
cur = cur.next;
}
}
return dummy.next;
};
虛擬頭節點技巧鞏固
82. Remove Duplicates from Sorted Listed II
給定一個有序連結串列,將其中有重複的元素全部刪除。
- 如1->2->3->3->4->4->5,返回1->2->5
- 如1->1->1->2->3,返回2->3
21. Merge Two Sorted Lists
merge兩個有序的連結串列
24. Swap Nodes in Pairs
給定一個連結串列,對於每兩個相鄰的節點,交換其位置。
- 如:連結串列為1->2->3->4->NULL
- 返回:2->1->4->3->NULL
- 只能對節點進行操作,不能修改節點的值
- 下圖next是不必要指標,但是去除最佳化效果不大
var swapPairs = function(head) {
var dummy = new ListNode(0);
dummy.next = head;
var n1 = dummy;
var n2 = head;
// 確認還有節點可以交換
while(n2 !== null && n2.next !== null){
// 儲存next節點,防止丟失
var nextStart = n2.next.next;
// 交換
n1.next = n2.next;
n1.next.next = n2;
n2.next = nextStart;
n1 = n2;
n2 = n2.next;
}
return dummy.next;
};
25. Reverse Nodes in k-Group
給定一個連結串列,每k個節點為一組,反轉每一組的k個節點。k為正整數且小於等於連結串列長度。如果連結串列長度不是k的整數倍,剩餘部分不需要進行反轉。如:1->2->3->4->5->NULL
- 若k=2,則結果為:2->1->4->3->5->NULL
- 若k=3,則結果為:3->2->1->4->5->NULL
147. Insertion Sort List
為一個連結串列進行插入排序
148. Sort List
寫一個排序演算法,用0(nlogn)的時間複雜度為一個連結串列進行排序
歸併排序
237. Delete Node in a Linked List
給定連結串列中的一個節點,刪除該節點
難點:不可能拿到刪除節點的前一個節點
解決思路: deleteNode = deleteNode->next, 然後刪除deleteNode->next(老辦法)
var deleteNode = function(node) {
if(node == null) return;
if(node.next === null){
node.val = null;
return;
}
node.val = node.next.val;
node.next = node.next.next;
};
雙指標技術
19. Remove Nth Node From End of List
給定一個連結串列,刪除倒數第n個節點
- 如:1->2->3->4->5->NULL,n=2
- 返回:1->2->3->5
- n從0計還是從1計
- n不合法,負數或者大於連結串列長度如何處理(保證n合法)
解法1:先遍歷一遍計算連結串列長度;再遍歷一遍刪除倒數第n個節點
- 遍歷兩遍連結串列。能否只遍歷一遍連結串列?
- 藉助兩個指標: 兩個指標間的距離相等
var removeNthFromEnd = function(head, n) {
var n1 = new ListNode();
var n2 = new ListNode();
var dummy = n2;
n1.next = head;
n2.next = head;
// 這裡判斷n1是為了防止傳入的n比連結串列總長度還要長
while(n > 0 && n1){
n1 = n1.next;
n--;
}
// 說明n確實比連結串列還要長。
if(n > 0){
return head;
}
// 經過上面的迴圈,n1和n2已經相差了n個結點
while(n1 && n1.next){
n1 = n1.next;
n2 = n2.next;
}
// 刪除
n2.next = n2.next.next;
return dummy.next;
};
61. Rotate List
給定一個連結串列,讓這個連結串列向右旋轉k位。其中k為非負數。
如:1->2->3->4->5->NULL,k=2
- 第一次旋轉:5->1->2->3->4->NULL
- 第二次旋轉:4->5->1->2->3->NULL
143.Reorder List
給定一個連結串列L(0)>L(1)>L(2)>.…>L(n-1)>L(n)
將其變為L(O)>L(n)->L(1)->L(n-1)->L(2)->L(n-2)……的形式
- 連結串列無法隨機訪問資料,如何獲得中間的元素?
- 兩次遍歷可以,但是一次遍歷怎麼獲取?
234.Palindrome Linked List
給一個連結串列,判斷這個連結串列是否為迴文連結串列。
- 能否使用0(1)的空間複雜度解決問題?
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4650/viewspace-2814742/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 面試 7:快慢指標法玩轉連結串列演算法面試(一)面試指標演算法
- 連結串列面試題(二)---連結串列逆序(連結串列反轉)面試題
- 演算法面試(一) 連結串列演算法面試
- 【LeetCode-連結串列】面試題-反轉連結串列LeetCode面試題
- 【資料結構之連結串列】詳細圖文教你花樣玩連結串列資料結構
- 面試必備的「反轉連結串列」面試
- 資料結構之連結串列:206. 反轉連結串列資料結構
- 劍指offer面試16 反轉連結串列面試
- 【圖解連結串列類面試題】移除連結串列元素圖解面試題
- 【圖解連結串列類面試題】環形連結串列圖解面試題
- 資料結構和演算法面試題系列—連結串列資料結構演算法面試題
- [演算法總結] 17 題搞定 BAT 面試——連結串列題演算法BAT面試
- 演算法-連結串列演算法
- 一個node連結串列翻轉的面試題面試題
- 連結串列專題——面試中常見的連結串列問題面試
- 連結串列面試題(七)---合併兩個有序連結串列面試題
- 每日演算法隨筆:反轉連結串列演算法
- 演算法題:反轉一個單連結串列&判斷連結串列是否有環演算法
- 【萬字】連結串列演算法面試?看我就夠了!演算法面試
- 反轉連結串列
- 旋轉連結串列
- 把玩演算法 | 連結串列演算法
- 資料結構和演算法——Go實現單連結串列並且反轉單連結串列資料結構演算法Go
- 03 Javascript資料結構與演算法 之 連結串列JavaScript資料結構演算法
- 《演算法筆記》6. 連結串列相關面試題總結演算法筆記面試題
- 連結串列面試題(九)---判斷一個連結串列是否帶環面試題
- 連結串列面試題(四)---查詢連結串列的中間節點面試題
- #反轉連結串列_C++版 #反轉連結串列_Java版 @FDDLCC++Java
- 反轉連結串列、合併連結串列、樹的子結構
- 面試題—資料結構之單連結串列詳述(基本篇)面試題資料結構
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 初級演算法-連結串列演算法
- 力扣--連結串列演算法力扣演算法
- 筆記--連結串列演算法筆記演算法
- 連結串列面試題(十一)---求帶環單連結串列 環的入口點面試題
- 資料結構實驗之連結串列九:雙向連結串列資料結構
- 資料結構實驗之連結串列二:逆序建立連結串列資料結構