[LeetCode] 23. Merge k Sorted Lists ☆☆
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
解法1:
采用递归的方法,不管合并几个,归根到底还是需要两两合并。
首先想到的是前两个先合并,然后再跟第三个合并,然后第四个。。。。但是这种做法效率不高。
换个思路,采用分治法,对数量超过2的任务进行拆分,直到最后只有一个或两个链表再进行合并。代码如下:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) { return null; } else if (lists.length == 1) { return lists[0]; } else { ListNode res = new ListNode(0); ListNode last = res; int mid = lists.length / 2; ListNode one = mergeKLists(Arrays.copyOfRange(lists, 0, mid)); ListNode two = mergeKLists(Arrays.copyOfRange(lists, mid, lists.length)); while (one != null && two != null) { if (one.val < two.val) { last.next = one; one = one.next; } else { last.next = two; two = two.next; } last = last.next; } last.next = one != null ? one : two; return res.next; } } }
或者:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) { return null; } int n = lists.length; while (n > 1) { int k = (n + 1) / 2; for (int i = 0; i < n / 2; i++) { lists[i] = mergeTwoLists(lists[i], lists[i + k]); } n = k; } return lists[0]; } public ListNode mergeTwoLists(ListNode list1, ListNode list2) { ListNode head = new ListNode(0); ListNode last = head; while (list1 != null && list2 != null) { if (list1.val < list2.val) { last.next = list1; list1 = list1.next; } else { last.next = list2; list2 = list2.next; } last = last.next; } last.next = list1 != null ? list1 : list2; return head.next; } }
解法2:
采用小根堆的方法,先将k个链表的首节点加入堆中,每次会自动输出最小的节点,将该节点加入到最终结果的链表中,然后将其下一个元素(如果不为null)加入堆中,直到最终堆为空,即输出了全部元素。代码如下:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>() { public int compare(ListNode left, ListNode right) { if (left == null) { return 1; // 这样操作的原因是,确保堆顶(最小节点)不会为null } else if (right == null) { return -1; // 这样操作的原因是,确保堆顶(最小节点)不会为null } // 因为下面操作中确保堆中不会有null,所以这两个判断不要亦可 return left.val - right.val; } }; public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) { return null; } Queue<ListNode> heap = new PriorityQueue<ListNode>(lists.length, ListNodeComparator); for (ListNode node : lists) { if (node != null) { heap.add(node); } } ListNode dummy = new ListNode(0); ListNode last = dummy; while (!heap.isEmpty()) { last.next = heap.poll(); last = last.next; if (last.next != null) { heap.add(last.next); } } return dummy.next; } }