题目:合并N个有序数组,每个数组的长度为M,合并为N*M的有序数组。时间复杂度要求最低
解法:N个数组进行两两合并,合并后的数组再继续执行合并过程,最后合成N*M的有序数组。可以认为合并这个递归过程发生了logN次,每一次合并的过程都是N*M个数合并,所以每一次合并的时间复杂度为N*M,总的时间复杂度就是N*M*logN
代码如下:
public class MergeArrays {
public static void main(String[] args) {
int[][] nums = {{1, 4, 8, 9}, {2, 3, 6, 10}, {5, 18, 20, 36}};
for (int num : mergeArray(nums)) {
System.out.println(num);
}
}
第一种方法:
static class Node implements Comparable<Node> {
int val;
int index;
int next;
public Node(int val, int index, int next) {
this.val = val;
this.index = index;
this.next = next;
}
@Override
public int compareTo(Node o) {
return this.val - o.val;
}
}
//合并N个M长度的有序数组
public static int[] mergeSortedArrays(int[][] arrays) throws Exception {
if (arrays == null || arrays.length == 0) {
throw new Exception("数组为空");
}
if (arrays.length == 1) {
return arrays[0];
}
int n = arrays.length;
int k = arrays[0].length;
int[] res = new int[n * k];
PriorityQueue<Node> pq = new PriorityQueue<>();
for (int i = 0; i < n; i++) {
pq.offer(new Node(arrays[i][0], i, 0));
}
int index = 0;
while (index < n * k) {
Node temp = pq.poll();
if (temp != null) {
res[index++] = temp.val;
if (temp.next + 1 < k) {
pq.offer(new Node(arrays[temp.index][temp.next + 1], temp.index, temp.next + 1));
}
}
}
return res;
}
第二中方法:
public static int[] mergeArray(int[][] nums) {
if (nums == null || nums.length == 0) {
return null;
}
if (nums.length == 1) {
return nums[0];
}
int len = nums.length;
boolean flag = len % 2 != 0;
int half = flag == true ? len / 2 + 1 : len / 2;
int[][] resultNums = new int[half][];
for (int i = 0; i < len+2; i += 2) {
if (flag && i == len - 1) {
resultNums[i / 2] = nums[i];
} else {
resultNums[i / 2] = mergeTwoArray(nums[i], nums[i + 1]);
}
}
return mergeArray(resultNums);
}
public static int[] mergeTwoArray(int[] num1, int[] num2) {
int len1 = num1.length;
int len2 = num2.length;
int index1 = 0;
int index2 = 0;
int index = 0;
int[] resultArray = new int[len1 + len2];
while (index1 < len1 && index2 < len2) {
if (num1[index1] < num2[index2]) {
resultArray[index++] = num1[index1++];
} else {
resultArray[index++] = num2[index2++];
}
}
while (index1 < len1) {
resultArray[index++] = num1[index1++];
}
while (index2 < len2) {
resultArray[index++] = num2[index2++];
}
return resultArray;
}
}