在O(1)空间中合并两个已排序的数组

时间:2016-03-28 01:56:16

标签: arrays sorting in-place

有人可以帮我理解这个问题的算法/代码

给定两个整数数组,对它们进行排序,使初始数字放在第一个数组中,剩余数字放在第二个数组中。 例如:

输入:ar1 [] = {1,5,9,10,15,20}

    ar2[] = {2, 3, 8, 13}

输出:ar1 [] = {1,2,3,5,8,9}

     ar2[] = {10, 13, 15, 20}  

代码:

    void merge(int ar1[], int ar2[], int m, int n)
{
    // Iterate through all elements of ar2[] starting from
    // the last element
    for (int i=n-1; i>=0; i--)
    {
        //Find the smallest element greater than ar2[i]. Move all
        //   elements one position ahead till the smallest greater
        //   element is not found
        int j, last = ar1[m-1];
        for (j=m-1; j >= 0 && ar1[j] > ar2[i]; j--)
            ar1[j+1] = ar1[j];

        // If there was a greater element
        if (j != m-1)
        {
            ar1[j+1] = ar2[i];
            ar2[i] = last;
        }
    }
}

我在这个网站上看到了这个解决方案:http://www.geeksforgeeks.org/merge-two-sorted-arrays-o1-extra-space/

2 个答案:

答案 0 :(得分:2)

直觉

对于ar2[i]的每个元素ar2(即在外部循环内),基本上你会在j中找到索引ar1,以便ar1的所有元素范围[(j+1), (m-1)]中的{}大于ar2[i]。然后你取出那个范围内的最小元素,并将从<{1}}中删除ar1,特别是索引为ar2的单元格,其中{的值为{ {1}}曾在转移到i之前居住过。

ar2[i]转移到ar1的原因是努力收集ar2[i]中的最小m个元素以及ar1[j+1]中的其余元素。这个算法所做的优雅的事情是从右到左穿越ar1。如果您还记得ar2ar2都已排序,ar1上从右到左有助于实现使用常量额外空间如下所示。

当您在ar2上从右向左走时,您会在ar2中遇到递减或至少不增加的值。这意味着您会发现ar2的递减或不递增值,以替换它们。基本上,大于ar2[i]的最小元素ar1[m-1]将不会增加,因为值ar1[m-1]随着我们从右到左的减少而减少。

因此,在外循环的每次迭代中我们抛出ar2[i]ar2[i]的元素也将以非递增或递减的顺序排列,我们将它们按降序排列到索引中,保持不变ar1命令。

不变方法

可能非常非正式的不变arr2ar2在每次迭代后排序,最多只有一个元素ar1,说ar2,其中存在至少1个ar2ar2[i]中的元素交换,其方式不违反任何一个数组的排序顺序。

最初订购的元素。每次迭代后,如果在ar1[k]>ar2[i]索引ar1中存在小于ar2[i]的元素,则大于ar1的所有范围都会向右移动1. {{1} }被放置到j,以便它不违反ar2[i]的顺序。然后,ar2[i]以前的最后元素不再适合ar1[j+1],而是ar1

可以直接看到在外循环的每次迭代中保持ar1的顺序。 ar1的顺序需要更多关注。

每当我们将ar2[i]的元素添加到ar1时,我们就会知道ar2的前一个元素,我们将放到ar2(即代替{已知{1}})大于ar1,因为它大于或等于ar1,大于ar2。 (ar2[i]

此外,ar2[i]中任何先前替换的元素(即ar1[j+1]的第i个索引右侧的元素)已被值 last 替换为大于或等于当前迭代中的最后一个值,因为最初订购了ar2[i]

因此,在每次迭代后,ar2[i] < ar1[j+1] <= last仍然是有序的,并且在算法终止后,没有元素ar2,因此存在元素ar2

答案 1 :(得分:0)

import java.util.Arrays;

公共类MergeArray {

public static void mergeArray(int[] input1, int[] input2)
{

    Arrays.sort(input1);


    for(int i=0; i<input1.length; i++) {

        for(int j=0; j<input2.length; j++) {

            if(input1[i]<input2[j]) {
                continue;
            }else {
                int temp = input1[i];
                input1[i]=input2[j];
                input2[j]=temp;
            }

        }

    }

    for(int i=0; i<input1.length; i++) {
        System.out.println(input1[i]);
    }
    Arrays.sort(input2);
    System.out.println("Array 2");
    for(int i=0; i<input2.length; i++) {
        System.out.println(input2[i]);
    }
}



public static void main(String[] args) {

    int[] array1= {2,7} ;   
    int[] array2= {5,3,8,1} ;
    mergeArray(array1,array2);



}

}