Leetcode23 合并K个升序链表
暴力解法很容易,JAVA 暴力解法:
public final ListNode mergeKLists(ListNode[] lists) { ListNode head = new ListNode(0); ListNode node = head; while (true) { int min = Integer.MAX_VALUE, minPoint = -1; for (int i = 0; i < lists.length; i++) { if (lists[i] == null) continue; if (lists[i].val < min) { min = lists[i].val; minPoint = i; } } if (minPoint == -1) break; node.next = lists[minPoint]; lists[minPoint] = lists[minPoint].next; node = node.next; } return head.next; }
JS 暴力解法:
var mergeKLists = function (lists) { let head = new ListNode(0), node = head; while (true) { let min = Number.MAX_VALUE, minPoint = -1; for (let i = 0; i < lists.length; i++) { if (!lists[i]) continue; if (lists[i].val < min) { min = lists[i].val; minPoint = i; } } if (minPoint === -1) break; node.next = lists[minPoint]; node = node.next; lists[minPoint] = lists[minPoint].next; } return head.next; };
暴力解法的渐进时间复杂度为 O(k2n) 。平方级及以上的渐进复杂度,如果可以缩小问题规模,性能的提升非常可观,因为其本身随着问题规模的扩大,增长率非常恐怖。因此可以考虑分治。
JAVA 分治:
public final ListNode mergeKLists(ListNode[] lists) { return merge(lists, 0, lists.length - 1); } private final ListNode merge(ListNode[] lists, int l, int r) { if (l == r) return lists[l]; if (l > r) return null; int mid = (l + r) >> 1; return mergeTwoList(merge(lists, l, mid), merge(lists, mid + 1, r)); } private final ListNode mergeTwoList(ListNode node1, ListNode node2) { if (node1 == null || node2 == null) return node1 == null ? node2 : node1; ListNode newHead = new ListNode(0), newNode = newHead; while (node1 != null && node2 != null) { int val1 = node1.val, val2 = node2.val; if (val1 <= val2) { newNode.next = node1; node1 = node1.next; } else { newNode.next = node2; node2 = node2.next; } newNode = newNode.next; } newNode.next = node1 == null ? node2 : node1; return newHead.next; }
JS 分治:
var mergeKLists = function (lists) { return merge(lists, 0, lists.length - 1); }; var merge = function (lists, l, r) { if (l == r) return lists[l]; if (l > r) return null; let mid = (l + r) >> 1; return mergeTwoList(merge(lists, l, mid), merge(lists, mid + 1, r)); } var mergeTwoList = function (node1, node2) { if ((!node1) || (!node2)) return !node1 ? node2 : node1; let newHead = new ListNode(0), newNode = newHead; while (node1 && node2) { if (node1.val <= node2.val) { newNode.next = node1; node1 = node1.next; } else { newNode.next = node2; node2 = node2.next; } newNode = newNode.next; } newNode.next = !node1 ? node2 : node1; return newHead.next; }
分治法下,时间复杂度为 O(kn×logk) 。
效果,暴力法:
分治法:
当你看清人们的真相,于是你知道了,你可以忍受孤独