简单题复杂做,下面给出两种写法:迭代、递归
// 迭代// 时间复杂度 : O(m + n)public ListNode mergeTwoLists(ListNode list1, ListNode list2) { ListNode dummy = new ListNode(-1); ListNode p = dummy; ListNode l1 = list1, l2 = list2; while (l1 != null && l2 != null) { if (l1.val <= l2.val) { p.next = l1; l1 = l1.next; } else { p.next = l2; l2 = l2.next; } p = p.next; } if (l1 == null) p.next = l2; else p.next = l1; return dummy.next;}
// 递归public ListNode mergeTwoLists(ListNode list1, ListNode list2) { if (list1 == null && list2 == null) return null; if (list1 == null || list2 == null) return list1 == null ? list2 : list1; if (list1.val <= list2.val) { list1.next = mergeTwoLists(list1.next, list2); return list1; } else { list2.next = mergeTwoLists(list1, list2.next); return list2; }}方法:和合并好的最后一个元素比较。如果相等,跳过;否则,合并
public ListNode mergeTwoLists(ListNode list1, ListNode list2) { ListNode p1 = list1, p2 = list2; ListNode dummy = new ListNode(-1000); ListNode p = dummy; while (p1 != null && p2 != null) { if (p1.val <= p2.val) { // 和前一个元素比较 if (p.val != p1.val) { p.next = p1; p = p.next; } p1 = p1.next; } else { // 和前一个元素比较 if (p.val != p2.val) { p.next = p2; p = p.next; } p2 = p2.next; } } while (p1 != null) { // 和前一个元素比较 if (p.val != p1.val) { p.next = p1; p = p.next; } p1 = p1.next; } while (p2 != null) { // 和前一个元素比较 if (p.val != p2.val) { p.next = p2; p = p.next; } p2 = p2.next; } return dummy.next;}可见题目 合并K个升序链表
// 两两合并// 时间复杂度 : O(k^2n) -> n + 2n + 3n + ... + kn = (1 + k) * k / 2// 空间复杂度 : O(1)public ListNode mergeKLists(ListNode[] lists) { if (lists.length == 0) return null; if (lists.length == 1) return lists[0]; ListNode h = lists[0]; for (int i = 1; i < lists.length; i++) { // mergeTwoLists() 见合并两个链表 h = mergeTwoLists(h, lists[i]); } return h;}
// 归并排序的思路// 时间复杂度 : O(nklogk) -> 每一层合并需要 O(nk),递归树的高度为 O(logk)// 空间复杂度 : 递归使用 O(logk) 栈空间public ListNode mergeKLists(ListNode[] lists) { if (lists.length == 0) return null; if (lists.length == 1) return lists[0]; return sort(lists, 0, lists.length - 1);}private ListNode sort(ListNode[] lists, int lo, int hi) { if (lo == hi) return lists[lo]; int mid = lo + hi >> 1; ListNode left = sort(lists, lo, mid); ListNode right = sort(lists, mid + 1, hi); // mergeTwoLists() 见合并两个链表 return mergeTwoLists(left, right);}
// 利用优先队列// 时间复杂度 : O(nklogk) -> offer() 操作时间复杂度为 O(logk)// 空间复杂度 : O(k)public ListNode mergeKLists(ListNode[] lists) { Queue<ListNode> q = new PriorityQueue<>((a, b) -> a.val - b.val); for (ListNode list : lists) { if (list != null) { q.offer(list); } } ListNode dummy = new ListNode(-1); ListNode p = dummy; while (!q.isEmpty()) { ListNode cur = q.poll(); p.next = cur; p = p.next; if (cur.next != null) q.offer(cur.next); } return dummy.next;}