Given k sorted integer arrays, merge them into one sorted array.
Example
Example 1:
Input:
[
[1, 3, 5, 7],
[2, 4, 6],
[0, 8, 9, 10, 11]
]
Output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Example 2:
Input:
[
[1,2,3],
[1,2]
]
Output: [1,1,2,2,3]
Challenge
Do it in O(N log k).
- N is the total number of integers.
- k is the number of arrays.
思路:divide and conquer, 跟merge sort类似。NlogK;
public class Solution {
/**
* @param arrays: k sorted integer arrays
* @return: a sorted array
*/
public int[] mergekSortedArrays(int[][] arrays) {
if(arrays == null || arrays.length == 0) {
return null;
}
return mergeKArrays(arrays, 0, arrays.length-1);
}
private int[] mergeKArrays(int[][] arrays, int start, int end) {
if(start == end) {
return arrays[start];
}
int mid = start + (end - start) / 2;
int[] left = mergeKArrays(arrays, start, mid);
int[] right = mergeKArrays(arrays, mid+1, end);
return mergeTwoSortedArray(left, right);
}
private int[] mergeTwoSortedArray(int[] left, int[] right) {
if(left == null || left.length == 0) return right;
if(right == null || right.length == 0) return left;
int[] res = new int[left.length + right.length];
int i = 0; int j = 0;
int index = 0;
while(i< left.length && j< right.length) {
if(left[i] < right[j]) {
res[index++] = left[i++];
} else {
res[index++] = right[j++];
}
}
while(i < left.length) {
res[index++] = left[i++];
}
while(j < right.length) {
res[index++] = right[j++];
}
return res;
}
}
思路2:用priorityQueue,需要建立element class去记录x,y,value的信息,还有建立一个myComparator的class,比较器。
NlogK.
public class Solution {
/**
* @param arrays: k sorted integer arrays
* @return: a sorted array
*/
private class Node {
int x;
int y;
int value;
public Node(int x, int y, int value) {
this.x = x;
this.y = y;
this.value = value;
}
}
private class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node a, Node b) {
return a.value - b.value;
}
}
public int[] mergekSortedArrays(int[][] arrays) {
if(arrays == null || arrays.length == 0) {
return new int[0];
}
PriorityQueue<Node> pq = new PriorityQueue<Node>(arrays.length, new NodeComparator());
// add each array's head into pq;
int size = 0;
for(int i = 0; i < arrays.length; i++) {
if(arrays[i].length > 0) {
pq.add(new Node(i, 0, arrays[i][0]));
size += arrays[i].length;
}
}
int[] res = new int[size];
int index = 0;
while(!pq.isEmpty()){
Node node = pq.poll();
res[index++] = node.value;
if(node.y+1 < arrays[node.x].length) {
pq.add(new Node(node.x, node.y+1, arrays[node.x][node.y+1]));
}
}
return res;
}
}
思路3:用buttom up的思想,两两merge,最后输出最后一个array
public class Solution {
/**
* @param arrays: k sorted integer arrays
* @return: a sorted array
*/
public int[] mergekSortedArrays(int[][] arrays) {
if(arrays == null || arrays.length == 0) {
return new int[0];
}
while(arrays.length > 1) {
int n = arrays.length / 2; // 注意,这里n需要除以2,因为是两两merge,长度减少一半;
if(arrays.length % 2 == 1) {
n++;
}
// 申请一个二维数组y = [0],二维数组是可以改的;
int[][] temp = new int[n][0];
int index = 0;
for(int i = 0; i + 1 < arrays.length; i += 2) {
int[] merge = mergeTwoSortedArrays(arrays[i], arrays[i+1]);
temp[index++] = merge;
}
if(arrays.length % 2 == 1) {
temp[index++] = arrays[arrays.length -1];
}
arrays = temp;
}
return arrays[0];
}
private int[] mergeTwoSortedArrays(int[] left, int[] right) {
if(left == null) return right;
if(right == null) return left;
int[] res = new int[left.length + right.length];
int i = 0; int j = 0;
int index = 0;
while(i < left.length && j < right.length) {
if(left[i] < right[j]) {
res[index++] = left[i++];
} else {
res[index++] = right[j++];
}
}
while(i < left.length) {
res[index++] = left[i++];
}
while(j < right.length) {
res[index++] = right[j++];
}
return res;
}
}