[每日一題] 第十八題:合併兩個排序的連結串列

DRose發表於2020-07-31

輸入兩個遞增排序的連結串列,合併這兩個連結串列並使新連結串列中的節點仍然是遞增排序的。

示例1:

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

限制:

  • 0 <= 連結串列長度 <= 1000

方法一:遍歷

解題思路:

  • 根據題目描述,連結串列 l1,l2 是 遞增 的,因此容易想到使用雙指標 l1 和 l2 遍歷兩連結串列,根據 l1.val 和 l2.val 的大小關係確定節點新增順序,兩節點指標交替前進,直至遍歷完畢。
  • 引入偽頭結點: 由於初始狀態合併連結串列中無節點,因此迴圈第一輪無法將節點新增到合併連結串列中,解決方案:初始化一個輔助節點 dum 作為合併連結串列的偽頭節點,將各節點新增至 dum 之後。

[每日一題] 第十八題:合併兩個排序的連結串列

演算法流程:

  1. 初始化: 偽頭節點 dum,節點 cur 指向 dum。

  2. 迴圈合併: 當 l1 或 l2 為空時跳出;

    1. 當 l1.val < l2.val 時:cur 的後繼節點指定為 l1,並 l1 向前一步;
    2. 當 l1.val >= l2.val 時:cur 的後繼節點指定為 l2,並 l2 向前走一步;
    3. 節點 cur 向前走一步,即 cur = cur.next
  3. 合併剩餘尾部: 跳出時有兩種挺狂,即 l1 為空 或 l2 為空。

    1. 若 l1 != null:將 l1 新增至節點 cur 之後;
    2. 否則:將 l2 新增至節點 cur 之後。
  4. 返回值: 合併連結串列在偽頭節點 dum 之後,因此返回 dum.next 即可。

程式碼

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dum = new ListNode(0), cur = dum;
        while(l1 != null && l2 != null) {
            if(l1.val < l2.val) {
                cur.next = l1;
                l1 = l1.next;
            }
            else {
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }
        cur.next = l1 != null ? l1 : l2;
        return dum.next;
    }
}

複雜度

  • 時間複雜度:O(M+N),M,N 分別為連結串列 l1,l2 的長度,合併操作需遍歷兩連結串列。
  • 空間複雜度:O(1):節點引用 dum,cur 使用常數大小的額外空間。

來源

作者:jyd
連結:leetcode-cn.com/problems/he-bing-l...
來源:力扣(LeetCode)

來源:力扣(LeetCode)
連結:leetcode-cn.com/problems/he-bing-l...

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章