1. 程式人生 > 其它 >【連結串列】題25-合併兩個排序的連結串列

【連結串列】題25-合併兩個排序的連結串列

技術標籤:劍指Offer演算法資料結構

1 題目描述

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

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

限制:

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

2 解題思路

首先比較兩個連結串列的頭節點,將指標newlist指向頭節點中較小的一個,然後將那個連結串列的頭節點指標向後移動一位來更新頭節點指標。然後進入迴圈,遍歷兩個連結串列,比較兩個連結串列的頭節點,將newlist.next指向較小的那個頭節點並更新此頭節點指標,最後向後移動newlist

,直到一個連結串列的頭節點為空結束迴圈,最後將newlist指向不為空的連結串列的頭節點。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
return l2; } else if (l2 == null) { return l1; } ListNode newlist; ListNode res; if (l1.val < l2.val) { newlist = l1; l1 = l1.next; } else { newlist = l2; l2 = l2.
next; } res = newlist; while (l1 != null && l2 != null) { if (l1.val < l2.val) { newlist.next = l1; l1 = l1.next; } else { newlist.next = l2; l2 = l2.next; } newlist = newlist.next; } if (l1 == null) { newlist.next = l2; } else { newlist.next = l1; } return res; } }

在這裡插入圖片描述

3 其他解題思路

3.1 方法1:偽頭節點(與上述方法相同)

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

3.2 方法2:遞迴法

與上述思路相同

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }
        else if (l2 == null) {
            return l1;
        }
        ListNode newlist;
        if (l1.val < l2.val) {
            newlist = l1;
            newlist.next = mergeTwoLists(l1.next,l2);
        }
        else {
            newlist = l2;
            newlist.next = mergeTwoLists(l1,l2.next);
        }
        return newlist;
    }
}