数据结构算法题/合并两个有序数组

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3(后面的三个0是额外的元素)
nums2 = [2,5,6],       n = 3

输出: 

[1,2,2,3,5,6]

(1)忽略nums1后面多余的元素,额外使用一个辅助数组C

时间O(m+n),空间复杂度O(m+n) 

假设两个有序数组都是升序,新建数组C,长度为数组A和数组B的长度之和,从索引0出依次设置数组C对于下标的值

/**
 * 合并两个有序数组
 * 假设两个有序数组都是升序,新建数组C,长度为数组A和数组B的长度之和,从索引0出依次设置数组C对于下标的值
 */
public class SortedArrayCombine {
    public static void main(String[] args) {
        int[] a = {1, 3, 5, 7, 9, 11, 13};
        int[] b = {2, 4, 6, 8, 10, 12};
        int[] c = new int[a.length + b.length];

        int i = 0;
        int j = 0;
        for (int k = 0; k < c.length; k++) {
            if (i < a.length && j < b.length) {//a和b都没走完
                if (a[i] <= b[j]) {
                    c[k] = a[i];
                    i++;
                } else {
                    c[k] = b[j];
                    j++;
                }
            } else if (i < a.length) {//或者else if(i < a.length && j >= b.length) 也就是b走完了
                c[k] = a[i];
                i++;
            } else if (j < b.length) {//或者else if(i >= a.length && j < b.length) 也就是a走完了
                c[k] = b[j];
                j++;
            } else {
                throw new RuntimeException("不可能情况");
            }
        }

        for (int k = 0; k < c.length; k++) {
            System.out.print(String.valueOf(c[k]) + " ");
        }
    }
}

(2)无辅助数组,时间复杂度为O(n+m),而空间复杂度为O(1)

思路

刚开始接触题就想到暴力解法,先将B加入到A的后面,然后对组合后的数组进行排序,假设A和B的长度分别是M,N,那么用快排平均也需要nlog(n)的时间复杂度;显然不是一种很好的做法;

第二种想法是再利用一个数组,然后A和B分别比较较小的元素加入到新的数组中,这样时间复杂度是O(M+N),但是空间复杂度又增加了O(M);这种也不是好办法;

第三种想法是在A的左边开始和b比较然后将B插入A中,这种算法移动元素的次数较多;移动一次的时间复杂度O(M),这种算法的时间复杂度是O(M*N);显然也不是好办法;

第四种,也是比较推荐的算法是,先算出A和B的总长度,由于数组中后面的元素是空的,可以从后往前复制,时间复杂度是O(M+N);空间复杂度是O(1);这种想法是比较好的,基于第四种算法的思想做了如下的Java实现
 

从大的开始比较和”入队“。 
比如1 3 5和2 4合并的话,从尾部比较: 
5比4大,5放到最后边; 
3比4小,4放到5的前面一格; 
3比2大,3放到4的前面一格; 
1比2小,2放到3的前面一格; 
1,没人来比较,1放到2的前面一格。 
END

public class SortedArrayCombine2 {
    public static void main(String args[]) throws Exception {
        int[] source1 = new int[50];
        source1[0] = 1;
        source1[1] = 2;
        source1[2] = 5;
        source1[3] = 9;
        source1[4] = 13;
        int[] source2 = new int[] { 1, 3, 4, 8, 10 };
        mergeArray(source1, source2, 5);
//        mergeArray(source1, source2, 100);
//        mergeArray(source1, null, 5);
//        mergeArray(null, source2, 5);
//        mergeArray(source1, source2, 4);
    }

    /**
     * @param source1
     * @param source2
     * m表示数组1已有数据长度这里是5
     * n表示数组2已有数据长度
     * length=m+n表示合并之后数组中的数据个数
     * @return
     */
    public static int[] mergeArray(int[] source1, int[] source2, int m) {
        /** 先进行判空,如果都非空,长度为0可认为是正确的 */
        if (source1 == null || source2 == null) {
            System.out.println("there is a null arr");
            return null;
        }
        /** source的长度和已有M不匹配 */
        if (m > source1.length) {
            System.out.println("the length unmatch with m");
            return null;
        }

        int n = source2.length;
        int length = m + n;//两个数组合并之后的新数组中元素的数量

        if (source1.length < length) {
            System.out.println("数组1的空间不够容纳数组1和2中的元素");
            return null;
        }

        int i = length - 1;
        // M+N次运算,上面都是一些特殊数据处理
        for (; i >= 0 && m > 0 && n > 0; i--) {
            //下面是把source1和source2中相对最大的那个放到合并的数组的后面(i = length - 1)
            if (source1[m - 1] > source2[n - 1]) {
                source1[i] = source1[m - 1];
                m--;
            } else {
                source1[i] = source2[n - 1];
                n--;
            }
        }
        // 比较完剩余的元素能顺利插入
        while (m > 0) {
            source1[i--] = source1[m--];
        }
        while (n > 0) {
            source1[i--] = source2[n--];
        }
        for (int count = 0; count < length; count++) {
            System.out.print(String.valueOf(source1[count]) + " ");
        }
        return source1;
    }
}

猜你喜欢

转载自blog.csdn.net/fkyyly/article/details/83145276