LeetCode 21 合併兩個有序鍊錶

2021-10-02 14:50:28 字數 1604 閱讀 5509

將兩個有序鍊錶合併為乙個新的有序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。

示例:輸入:1->2->4, 1->3->4

輸出:1->1->2->3->4->4

我們可以如下遞迴地定義在兩個煉表裡的 merge 操作(忽略邊界情況,比如空煉表等):

也就是說,兩個鍊錶頭部較小的乙個與剩下元素的 merge 操作結果合併。

演算法我們直接將以上遞迴過程建模,首先考慮邊界情況。

特殊的,如果 l1 或者 l2 一開始就是 null ,那麼沒有任何操作需要合併,所以我們只需要返回非空鍊錶。否則,我們要判斷 l1 和 l2 哪乙個的頭元素更小,然後遞迴地決定下乙個新增到結果裡的值。如果兩個鍊錶都是空的,那麼過程終止,所以遞迴過程最終一定會終止。

複雜度分析

時間複雜度:o(n+m)。 因為每次呼叫遞迴都會去掉 l1 或者 l2 的頭元素(直到至少有乙個鍊錶為空),函式 mergetwolist 中只會遍歷每個元素一次。所以,時間複雜度與合併後的鍊錶長度為線性關係。

空間複雜度:o(n+m)。呼叫 mergetwolists 退出時 l1 和 l2 中每個元素都一定已經被遍歷過了,所以 n+m 個棧幀會消耗 o(n+m) 的空間。

我們可以用迭代的方法來實現上述演算法。我們假設 l1 元素嚴格比 l2元素少,我們可以將 l2 中的元素逐一插入 l1 中正確的位置。

演算法首先,我們設定乙個哨兵節點 「prehead」 ,這可以在最後讓我們比較容易地返回合併後的鍊錶。我們維護乙個 prev 指標,我們需要做的是調整它的 next 指標。然後,我們重複以下過程,直到 l1 或者 l2 指向了 null :如果 l1 當前位置的值小於等於 l2 ,我們就把 l1 的值接在 prev 節點的後面同時將 l1 指標往後移乙個。否則,我們對 l2 做同樣的操作。不管我們將哪乙個元素接在了後面,我們都把 prev 向後移乙個元素。

在迴圈終止的時候, l1 和 l2 至多有乙個是非空的。由於輸入的兩個鍊錶都是有序的,所以不管哪個鍊錶是非空的,它包含的所有元素都比前面已經合併鍊錶中的所有元素都要大。這意味著我們只需要簡單地將非空鍊錶接在合併鍊錶的後面,並返回合併鍊錶。

/**

* definition for singly-linked list.

* public class listnode

* }*/class

solution

else

if(l2 == null)

else

if(l1.val < l2.val)

else

}}

/**

* definition for singly-linked list.

* public class listnode

* }*/class

solution

else

prev = prev.next;

} prev.next = l1 == null?l2:l1;

return prehead.next;

}}

LeetCode 21合併兩個有序列表

將兩個公升序鍊錶合併為乙個新的公升序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。輸入 1 2 4,1 3 4 輸出 1 1 2 3 4 4初始解法 這個問題轉換為經典的merge排序中的merge過程.merge排序中merge操作即是將兩個有序子陣列合併成乙個陣列,需要考慮比較過程...

leetcode21 合併兩個有序鍊錶

將兩個有序鍊錶合併為乙個新的有序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。示例 輸入 1 2 4,1 3 4 輸出 1 1 2 3 4 4 思路 每次判斷兩個鍊錶的頭部小的數值,訪問小的,並讓該鍊錶往後移動。注意 注意鍊錶走完,為空的情況即可。遇到的問題 一開始不太理解鍊錶,返回e...

LEETCODE 21 合併兩個有序鍊錶

將兩個有序鍊錶合併為乙個新的有序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。示例 輸入 1 2 4,1 3 4 輸出 1 1 2 3 4 4c 第一遍將 相等 的這個else分支寫錯了,主要錯誤在於,next指標指向下乙個的這條語句寫到了後面,導致節點自己指向自己,造成了超時錯誤 執...