Merge k sorted array
//General idea 1: use min-heap to sort the collection of one element from each array. Everytime the heap poll out an element, put it into the result array. The point is that we need to new a class to store the value, index and which array.
class Solution {
class Array {
int value;
int arrayId;
int index;
Array(int value, int index, int arrayId) {
this.value = value;
this.index = index;
this.arrayId = arrayId;
}
}
public List<Integer> merge(List<List<Integer>> list) {
List<Integer> result = new ArrayList<>();
Comparator<Array> com = new Comparator() {
public int compare(Array array1, Array array2) {
return array1.value - array2.value;
}
};
PriorityQueue<Array> heap = new PriorityQueue<>(com);
for (int i = 0; i < list.size(); i++) {
Array array = new Array(list.get(i).get(0), 0, i);
heap.offer(array);
}
while (!heap.isEmpty()) {
Array array = heap.poll();
result.add(array.value);
if (array.index < list.get(array.arrayId).size() - 1) {
heap.offer(list.get(array.arrayId).get(array.index + 1));
}
}
return result;
}
}
//General idea 2: use binary search, and merge sort idea, The time complexity is O(knlogn)
public ListNode merge(ListNode[] list) {
if (list == null || list.length == 0) return null;
if (list.length == 1) return list[0];
int len = list.length;
while (len > 1 ) {
int mid = (len + 1) / 2;
for (int i = 0; i < len / 2; i++) {
list[i] = mergeTwoList(list[i], list[i + mid]);
}
len = mid;
}
return list[0];
}
public ListNode mergeTwoList(ListNode list1, ListNode list2) {
if (list1 == null && list2 == null) return null;
if (list1 == null) return list2;
if (list2 == null) return list1;
ListNode head = new ListNode(-1), cur = head;
ListNode index1 = list1, index2 = list2;
while (index1 != null && index2 != null) {
if (index1.val <= index2.val) {
cur.next = index1;
cur = index1;
index1 = index1.next;
} else {
cur.next = index2;
cur = index2;
index2 = index2.next;
}
}
if (index1 != null) cur.next = index1;
if (index2 != null) cur.next = index2;
return head.next;
}