Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
合并k个有序链表。
最直接的想法先合并两条链表,然后再与第三条链表进行合并,那么时间复杂度是o(2n+3n……kn)=o(nk²)
另一种想法是借鉴归并排序的思想,两两合并。T(n)=2T(n/c)+cn,可得复杂度为o(klogn)
还可以使用堆排序的思想。把每个链表的头结点放入堆中。每次找到最小的加入到新的链表中。建堆复杂度为klog(k),每次处理新节点为log(k),总复杂度nklog(k)。
代码如下:
/**链表合并 * @param lists * @return */ public static ListNode mergeKLists(ListNode[] lists) { if (lists.length == 0) return null; if (lists.length == 1) return lists[0]; ListNode head = new ListNode(0); ListNode resultList = head; int heapSize = 0; for (ListNode node : lists) if (node != null) heapSize++; lists = initHeap(lists, heapSize); while (heapSize > 0) { ListNode node = new ListNode(lists[0].val); head.next = node; head = head.next; if (lists[0].next == null) { lists[0] = lists[heapSize - 1]; heapSize--; lists = minHeap(lists, 0, heapSize); } else { lists[0] = lists[0].next; lists = minHeap(lists, 0, heapSize); for (ListNode n : lists) System.out.print(n.val + ","); System.out.println(); } } return resultList.next; } /** 初始化堆 * @param lists * @param heapSize * @return */ public static ListNode[] initHeap(ListNode[] lists, int heapSize) { for (int i = 0; i < lists.length; i++) { if (lists[i] == null) { for (int j = lists.length - 1; j > i; j--) { if (lists[j] != null) { lists[i] = lists[j]; break; } } } } int l = (int) (Math.ceil(heapSize / 2) - 1); while (l >= 0) { lists = minHeap(lists, l, heapSize); l--; } return lists; } /**最小化堆 * @param lists * @param l * @param heapSize * @return */ public static ListNode[] minHeap(ListNode[] lists, int l, int heapSize) { int min = 0; if (l * 2 + 1 > heapSize - 1) { return lists; } else if (l * 2 + 2 > heapSize - 1) {// only has right child min = l * 2 + 1; } else {// has left and right child if (lists[l * 2 + 2].val > lists[l * 2 + 1].val) min = l * 2 + 1; else min = l * 2 + 2; } if (lists[min].val < lists[l].val) { ListNode node = lists[min]; lists[min] = lists[l]; lists[l] = node; if (2 * min + 1 <= heapSize - 1) lists = minHeap(lists, min, heapSize); } else { return lists; } return lists; }