NO.21题目
思路
借用归并排序过程中的合并思想,分而治之
代码实现:递归法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if not l1:
return l2
if not l2:
return l1
head = None
if l1.val <= l2.val:
head = l1
head.next = self.mergeTwoLists(l1.next,l2)
else:
head = l2
head.next = self.mergeTwoLists(l1,l2.next)
return head
迭代法:
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
# 归并排序
dummy_head = ListNode()
cur = dummy_head
p1, p2 = list1, list2
while p1 and p2:
if p1.val <= p2.val:
cur.next = p1
p1 = p1.next
else:
cur.next = p2
p2 = p2.next
cur = cur.next
# 任一为空,直接连接另一条链表
if not p1:
cur.next = p2
if not p2:
cur.next = p1
# while p1:
# cur.next = p1
# cur = cur.next
# p1 = p1.next
# while p2:
# cur.next = p2
# cur = cur.next
# p2 = p2.next
return dummy_head.next
java版
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 终止条件
if (list1 == null){
return list2;
} else if (list2 == null){
return list1;
} else if (list1.val < list2.val){
list1.next = mergeTwoLists(list1.next, list2);
return list1;
} else {
list2.next = mergeTwoLists(list1, list2.next);
return list2;
}
}
}
NO.23题目
思路一:暴力法
- 遍历所有链表,将所有节点的值放到一个数组中。
- 将这个数组排序,然后遍历所有元素得到正确顺序的值。
- 用遍历得到的值,创建一个新的有序链表。
代码实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
l = []
#创建一个头节点
head = cur = ListNode(0)
#先遍历进list
for i in lists:
while i:
l.append(i.val)
i = i.next
#连起来
for j in sorted(l):
cur.next = ListNode(j)
cur = cur.next
return head.next #返回头节点的下一个节点
复杂度分析
- 1时间复杂度
- 遍历所有的值需花费 O(N) 的时间。
- 一个稳定的排序算法花费 O(N\log N)的时间。
- 遍历同时创建新的有序链表花费O(N)的时间。
所以时间复杂度为O(N\log N)
- 2空间复杂度O(N)
思路二:分治
在21题的基础上,借助归并排序的思想,递归的对数组进行两两合并
代码实现
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if not lists:return
n = len(lists)
return self.merge(lists, 0, n-1)
def merge(self,lists, left, right):
#边界条件
if left == right:
return lists[left]
mid = left + (right - left) // 2
#本轮要做什么:左边和右边分别merge
l1 = self.merge(lists, left, mid)
l2 = self.merge(lists, mid+1, right)
#返回值:已经排好序的链表
return self.mergeTwoLists(l1, l2)
#两链表合并:即第21题
def mergeTwoLists(self,l1, l2):
if not l1:return l2
if not l2:return l1
if l1.val < l2.val:
l1.next = self.mergeTwoLists(l1.next, l2)
return l1
else:
l2.next = self.mergeTwoLists(l1, l2.next)
return l2
20221206版本-非递归写法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) return null;
return merge(lists, 0, lists.length - 1);
}
public ListNode merge(ListNode[] lists, int left, int right){
if (left == right){
return lists[left];
}
int mid = left + (right - left) / 2;
ListNode l = merge(lists, left, mid);
ListNode r = merge(lists, mid + 1, right);
return mergeTwoLists(l, r);
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2){
ListNode head = new ListNode(0);
//终止条件
if (l1 == null || l2 == null){
return l1 == null ? l2 : l1;
}
ListNode tail = head, a = l1, b = l2;
while(a != null && b != null){
if (a.val < b.val){
tail.next = a;
a = a.next;
} else {
tail.next = b;
b = b.next;
}
tail = tail.next;
}
tail.next = (a == null ? b : a);
//递归处理,当前要做什么
// if (l1.val < l2.val){
// head = l1;
// head.next = mergeTwoList(l1.next, l2);
// } else {
// head = l2;
// head.next = mergeTwoList(l1, l2.next);
// }
return head.next;
}
}