【问题标题】:Merge sorted arrays?合并排序数组?
【发布时间】:2024-01-15 16:15:01
【问题描述】:

如何合并和打印两个没有任何重复的排序数组?我尝试过但无法找到任何有效的解决方案。

public static void mergeSortedArrays(int a[], int b[]) {
    int[] answer = new int[a.length + b.length];
    int i = 0, j = 0, k = 0;
    while (i < a.length && j < b.length)  
        answer[k++] = a[i] < b[j] ? a[i++] :  b[j++];

    while (i < a.length)
        answer[k++] = a[i++];

    while (j < b.length)    
        answer[k++] = b[j++];

    System.out.print(answer);
}

【问题讨论】:

  • 您分享的解决方案到底有什么问题?
  • 问题是它不能消除重复。

标签: java arrays sorting merge


【解决方案1】:

您说两个数组都已排序,我假设合并后的数组也需要排序。

这里是代码。解释如下。
(注意:由于 OP comment 已编辑代码。)

import java.util.Arrays;

public class Test {

    private static int[] mergeSortedArrays(int[] a, int[] b) {
        int[] temp = new int[a.length + b.length];
        int i = 0;
        int j = 0;
        int k = 0;
        while (i < a.length) {
            if (j < b.length) {
                if (a[i] < b[j]) {
                    temp[k++] = a[i++];
                }
                else if (a[i] == b[j]) {
                    temp[k++] = a[i++];
                    j++;
                }
                else {
                    temp[k++] = b[j++];
                }
            }
            else {
                temp[k++] = a[i++];
            }
        }
        if (j < b.length) {
            for (; j < b.length; j++) {
                temp[k++] = b[j];
            }
        }
        int[] answer = new int[k];
        System.arraycopy(temp, 0, answer, 0, k);
        /* Added */
        System.out.print(answer[0]);
        for (i = 1; i < k; i++) {
            System.out.print(", " + answer[i]);
        }
        System.out.println();
        /**/
        return answer;
    }

    public static void main(String[] args) {
        int[] a = {-19, -5, -4, 3, 7, 8, 11, 21};
        int[] b = {-7, -5, -4, 0, 3, 6, 11, 13, 20};
        System.out.println(Arrays.toString(mergeSortedArrays(a, b)));
    }
}

我们将第一个数组中的一个元素与第二个数组中的一个元素进行比较。两者中较小的一个被复制到结果数组中。然后我们增加其元素被复制到结果数组的数组的索引。如果元素相等,我们[任意]从第一个数组复制元素并增加两个数组的索引。这可以防止结果数组包含重复项。

如果数组的元素数量不相等,那么当我们用完一个数组时,我们只需将较长数组中的所有剩余元素复制到结果数组中。

因此结果数组包含两个数组中的所有元素,没有重复,已排序。

这是我运行上述代码时的输出。

-19, -7, -5, -4, 0, 3, 6, 7, 8, 11, 13, 20, 21
[-19, -7, -5, -4, 0, 3, 6, 7, 8, 11, 13, 20, 21]

【讨论】:

  • 如果我想用同样的方法打印答案而不返回,我需要做什么?
  • @MohitSharma 在方法 mergeSortedArrays 中的行 return answer 之前添加行 System.out.println(Arrays.toString(answer));
  • 没错,但我不想在'[]'这些括号内打印我的答案
  • @MohitSharma 答案已编辑。
【解决方案2】:

根据您的代码,输出中会有重复项。要删除重复项,您需要在第一时间将条件修改为此:

while (i < a.length && j < b.length)  
   answer[k++] = a[i] <= b[j] ? a[i++] :  b[j++];

这将跳过其他数组中的重复项之一。

还需要检查输出数组是否已经包含上一个索引中的相同元素并跳过。

while (i < a.length && j < b.length)  {
    if(answer[k] == a[i]) 
        i++;
    else if(answer[k] == b[j]) 
        j++;
    else 
        answer[k++] = a[i] <= b[j] ? a[i++] :  b[j++];
}

其他时间也是如此。

【讨论】:

    【解决方案3】:

    结果是排序和不同的元素作为 int 数组。

            int[] c = new int[a.length + b.length];
            int maxLength = a.length > b.length ? a.length : b.length;
    
            for(int i = 0, j = 0; i < maxLength; i++) {
                if(i < a.length) {
                    c[j] = a[i];
                    j++;
                }
                if(i < b.length) {
                    c[j] = b[i];
                    j++;
                }
            }
    
            int[] result = Arrays.stream(c).sorted().distinct().toArray();
    

    【讨论】: