【两次过】【归并】Lintcode 486. 合并k个排序数组

将 k 个有序数组合并为一个大的有序数组。

样例

样例 1:

输入:
  [
    [1, 3, 5, 7],
    [2, 4, 6],
    [0, 8, 9, 10, 11]
  ]
输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

样例 2:

输入: 
  [
    [1,2,3],
    [1,2]
  ]
输出: [1,1,2,2,3]

挑战

在 O(N log k) 的时间复杂度内完成:

  • N 是所有数组包含的整数总数量。
  • k 是数组的个数。

解题思路:

分治法下的归并。我们知道合并两个排序数组直接使用merge即可,而合并k个可以将其看作两部分,左边归并后的结果与右边归并后的结果,然后再merge。

递归出口是l==r,代表只有一个有序数组直接返回,l+1==r,代表刚好两个有序数组直接merge。

public class Solution {
    /**
     * @param arrays: k sorted integer arrays
     * @return: a sorted array
     */
    public int[] mergekSortedArrays(int[][] arrays) {
        // write your code here
            if(arrays == null || arrays.length == 0)
                return null;
            
            return helper(arrays, 0, arrays.length-1);

    }
    
    private int[] helper(int[][] arrays, int l, int r){
        if(l == r)
            return arrays[l];
        if(l + 1 == r)
            return merge2Arrays(arrays[l], arrays[r]);
        
        int mid = l + (r-l)/2;
        int[] left = helper(arrays, l, mid);
        int[] right = helper(arrays, mid+1, r);
        
        return merge2Arrays(left, right);
    }
    
    private int[] merge2Arrays(int[] a, int[] b){
        int[] res = new int[a.length + b.length];
        
        int i=0, j=0;
        for(int k=0; k= a.length)
                res[k] = b[j++];
            else if(j >= b.length)
                res[k] = a[i++];
            else if(a[i] < b[j])
                res[k] = a[i++];
            else
                res[k] = b[j++];
        }
        
        return res;
    }
}

 

 

你可能感兴趣的:(lintcode,数组)