0.合并两个已经排好序的链表
迭代写法:
public ListNode Merge(ListNode list1,ListNode list2) {
if (list1 == null || list2 == null) {
return list1 != null ? list1 : list2;
}
ListNode res = new ListNode(-1);
ListNode cur = res;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
cur.next = list1;
list1 = list1.next;
} else {
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
if (list1 != null || list2 != null) {
cur.next = list1 != null ? list1 : list2;
}
return res.next;
}
迭代思想:用一个指针在两个链表之间移动,每次移动到较小元素位置上
时间复杂度O(N+M)
空间复杂度O(1)
递归写法:
public ListNode Merge(ListNode list1,ListNode list2) {
if (list1 == null || list2 == null) {
return list1 != null ? list1 : list2;
}
if (list1.val < list2.val) {
list1.next = Merge(list1.next, list2);
}
else {
list2.next = Merge(list1, list2.next);
}
return list1.val < list2.val ? list1 : list2;
}
递归思想:递归返回两个链表中剩下的当前元素较小的部分
时间复杂度O(N+M)
空间复杂度O(1)
1.合并K个自增排序的链表
采用分治的思想,将k个链表两两合并,再对合并后的结果进行合并,两个链表合并的实现和上面一样,主要是如何划分链表集合,这次采用二分划分:
public ListNode merge(ListNode list1, ListNode list2) {
if (list1 == null || list2 == null) {
return list1 != null ? list1 : list2;
}
ListNode res = new ListNode(-1);
ListNode cur = res;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
cur.next = list1;
list1 = list1.next;
} else {
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
if (list1 != null || list2 != null) {
cur.next = list1 != null ? list1 : list2;
}
return res.next;
}
ListNode divideList(ArrayList<ListNode> lists, int left, int right) {
if (left > right) {
return null;
}
else if (left == right) {
return lists.get(left);
}
int mid = (left + right) / 2;
return merge(divideList(lists, left, mid), divideList(lists, mid+1, right));
}
public ListNode mergeKLists(ArrayList<ListNode> lists) {
return divideList(lists, 0, lists.size()-1);
}
时间复杂度O(NlogK)
空间复杂度O(N*K)