【LeetCode題解】21_合併兩個有序連結串列
阿新 • • 發佈:2018-11-23
21_合併兩個有序連結串列
文章目錄
描述
將兩個有序連結串列合併為一個新的有序連結串列並返回。新連結串列是通過拼接給定的兩個連結串列的所有節點組成的。
示例:
輸入:1->2->4, 1->3->4 輸出:1->1->2->3->4->4
解法一:迭代
思路
因為兩個連結串列都是有序連結串列(遞增),因此可以很容易地找出兩個連結串列中的最小元素,即比較兩個連結串列表頭的元素,時間複雜度是 的。我們可以利用兩個指標——指向兩個連結串列的最小節點,每次比較兩個指標所指向節點的值,將值比較小的節點加到新的連結串列中,然後更新指標,如此迴圈往復直到到達一個連結串列的尾部。最後,還需要將另一個連結串列的剩餘部分(如果存在的話)新增到新的連結串列的尾部。
Java 實現
/**
* 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) {
ListNode dummyHead = new ListNode(0);
ListNode lastNode = dummyHead;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
lastNode.next = l1;
l1 = l1.next;
} else {
lastNode.next = l2;
l2 = l2.next;
}
lastNode = lastNode.next;
}
lastNode.next = l1 != null ? l1 : l2;
return dummyHead.next;
}
}
// Runtime: 9 ms
// Your runtime beats 86.44 % of java submissions.
複雜度分析:
- 時間複雜度: ,其中, 為連結串列 1 的節點數, 為連結串列 2 的節點數,演算法需要遍歷兩個連結串列的所有元素
- 空間複雜度: ,只需要儲存兩個引用
Python 實現
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
dummy_head = last_node = ListNode(0)
while l1 and l2:
if l1.val < l2.val:
last_node.next = l1
l1 = l1.next
else:
last_node.next = l2
l2 = l2.next
last_node = last_node.next
last_node.next = l1 or l2
return dummy_head.next
# Runtime: 44 ms
# Your runtime beats 99.24 % of python3 submissions.
複雜度分析同上。
解法二:遞迴
思路
遞迴的思路和迭代的思路是相同的,都是每次比較兩個連結串列的最小節點,然後對值更小的節點進行操作。不同的是,迭代是從值比較小的節點開始組建新的連結串列,而遞迴則是從值比較大的節點開始組建新的連結串列——遞迴到其中一個連結串列的尾部才開始組建新的連結串列。
Java 實現
/**
* 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 || l2 == null) {
return l1 != null ? l1 : l2;
}
if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
// Runtime: 8 ms
// Your runtime beats 99.96 % of java submissions.
複雜度分析:
- 時間複雜度: ,其中, 為連結串列 1 的節點數, 為連結串列 2 的節點數,演算法需要遍歷兩個連結串列的所有元素
- 空間複雜度: ,額外的空間是由於遞迴呼叫佔用系統棧的空間,遞迴的深度最多為 層
Python 實現
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if not l1 or not l2:
return l1 or l2
if l1.val < l2.val:
l1.next = self.mergeTwoLists(l1.next, l2)
return l1
else:
l2.next = self.mergeTwoLists(l1, l2.next)
return l2
複雜度分析同上。