將兩個公升序鍊錶合併為乙個新的公升序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。
示例:
輸入:1->2->4, 1->3->4思路輸出:1->1->2->3->4->4
我們可以如下遞迴地定義兩個煉表裡的merge
操作(忽略邊界情況,比如空煉表等):
也就是說,兩個鍊錶頭部值較小的乙個節點與剩下元素的merge
操作結果合併。
我們直接將以上遞迴過程建模,同時需要考慮邊界情況。
我們要先判斷給定 兩個鍊錶是否為空鍊錶 ,那麼沒有任何操作需要合併,所以我們只需要返回非空鍊錶。否則,我們要判斷l1
和l2
頭結點哪個更小,然後較小結點的next
指標指向其餘結點的合併結果。(呼叫遞迴)如果兩個鍊錶有乙個為空,遞迴結束。
示例**
/**複雜度分析 \* definition for singly-linked list.
\* struct listnode
\* listnode(int x) : val(x), next(nullptr) {}
\* listnode(int x, listnode *next) : val(x), next(next) {}
\* };
*/
class solution
else }};
思路迭代的話,我們要兩個鍊錶中乙個乙個元素拿出來比,所以為了操作方便,我們可以另建鍊錶,然後依次將較小元素追加到新建鍊錶後邊。為了比較完之後知道要將元素插在**,所以要記錄一下最後插入元素的位置。
首先,我們設定乙個哨兵節點 head ,這可以在最後讓我們比較容易地返回合併後的鍊錶。
然後維護乙個 prev 指標,來記錄最後插入元素的位置,方便l1、l2比較完之後快速插入。我們需要做的是調整它的 next 指標。
我們重複以下過程,直到 l1 或者 l2 中沒有元素。如果 l1 當前節點的值小於等於 l2 ,我們就把 l1 當前的節點追加在 prev 節點的後面同時將 l1 指標往後移一位。否則,我們對 l2 做同樣的操作。不管我們將哪乙個元素追加在新鍊錶後面,我們都需要移動 prev 的位置。
在迴圈終止的時候, l1 和 l2 至多有乙個是非空的。由於輸入的兩個鍊錶都是有序的,所以不管哪個鍊錶是非空的,它包含的所有元素都比前面已經合併鍊錶中的所有元素都要大。所以我們只需要將剩下的非空鍊錶追加到新鍊錶後邊,並返回新鍊錶即可。
示例**
/**複雜度分析* definition for singly-linked list.
* struct listnode
* listnode(int x) : val(x), next(nullptr) {}
* listnode(int x, listnode *next) : val(x), next(next) {}
* };
*/class solution
else
// 插入乙個元素,記錄指標後移
prenode = prenode->next;
}// 找剩下的非空鍊錶,將其剩餘元素全部追加到新鍊錶中
l1 == nullptr ? prenode->next = l2 : prenode->next = l1;
return head->next;}};
合併兩個有序鍊錶
鍊錶的題目總是讓我很惆悵。動輒就會runtime error。比如這題,額外用了乙個節點的空間來儲存頭節點。我很不情願多用這個空間,不過貌似不行。貌似不行,實際可行,見附錄。把頭節點提出迴圈 實現類 class solution else if l1 null p next l1 if l2 nul...
合併兩個有序鍊錶
三個指標乙個儲存la鍊錶 乙個儲存lb鍊錶,乙個指向新的鍊錶。鍊錶的插入,兩個指標,乙個是head,乙個指向head後面的鏈,新插入的元素位於head後面。執行該 自己外加上class類。static class node public static void main string args st...
合併兩個有序鍊錶
將兩個有序鍊錶合併為乙個新的有序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。示例 輸入 1 2 4,1 3 4 輸出 1 1 2 3 4 4思路 很簡單就是二路歸併的思想,時間複雜度o n definition for singly linked list.struct listno...