[LeetCode] 23. Merge k Sorted List
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Time complexity:
Thought process:
Algorithm 1: Divide and conquer. Break k lists into pairs and merge a pair at a time.
Algorithm 2: Use a heap. At the start, offer the first element of each list into the heap. While the heap is not empty, poll the first element from it, and offer first.next into the heap.
Algorithm 2: Use a heap. At the start, offer the first element of each list into the heap. While the heap is not empty, poll the first element from it, and offer first.next into the heap.
Solution 1 (Divide and conquer):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /** * 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.length == 0) { return null; } return mergeKLists(lists, 0, lists.length - 1); } private ListNode mergeKLists(ListNode[] lists, int start, int end) { if (start == end) { return lists[start]; } int mid = start + (end - start) / 2; ListNode left = mergeKLists(lists, start, mid); ListNode right = mergeKLists(lists, mid + 1, end); return merge(left, right); } private ListNode merge(ListNode left, ListNode right) { ListNode dummy = new ListNode(0); ListNode current = dummy; while (left != null && right != null) { if (left.val < right.val) { current.next = left; left = left.next; } else { current.next = right; right = right.next; } current = current.next; } if (left != null) { current.next = left; } else { current.next = right; } return dummy.next; } } |
Time complexity:
There are k lists, so there are logk recurrences. At each recurrence, merge takes O(n). So the overall time complexity is O(nlogk).
Solution 2 (Heap):
Time complexity:
Every iteration takes O(logk). Say there're n total list nodes. The total number of iterations is n. So the overall time complexity is O(nlogk).
Solution 2 (Heap):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode mergeKLists(ListNode[] lists) { ListNode dummy = new ListNode(0); PriorityQueue<ListNode> heap = new PriorityQueue<>((a, b) -> a.val - b.val); for (ListNode node : lists) { if (node != null) { heap.offer(node); } } ListNode current = dummy; while (!heap.isEmpty()) { ListNode node = heap.poll(); if (node.next != null) { heap.offer(node.next); } current.next = node; current = current.next; } return dummy.next; } } |
Time complexity:
Every iteration takes O(logk). Say there're n total list nodes. The total number of iterations is n. So the overall time complexity is O(nlogk).
Comments
Post a Comment