【问题标题】:Copied unique values from sorted array to new array***将唯一值从排序数组复制到新数组***
【发布时间】:2017-04-10 19:29:40
【问题描述】:

我正在为我的数据结构类解决一个 Java 问题。

本质上,我们应该获取一个排序数组,从中删除所有重复项,然后将这些唯一值复制到一个新数组中。然而,具有挑战性的一点是我们只被允许遍历数组一次。我遇到的每个解决方案都需要至少遍历数组两次:一次用于“删除”重复值,另一次将唯一值复制到新数组中。

在识别唯一值的过程中,有什么方法可以将唯一值复制到新数组中?我正在用头撞墙,遇到各种 OutOfBounds 异常,试图弄清楚这一点。

我还应该提到,数组的大小被认为是给定的。

感谢阅读!

这是我目前创建新数组的代码:

public static double[] removeDuplicates (double[] list) {

        int numOfUniques = numUnique(list);
        if (numOfUniques == 0){
            return null;
        }
        else if (list.length < 2){
            return list;
        }

        int counter = 0;
        double[] uniquesArray = new double[numOfUniques];
        uniquesArray[0] = list[0];

        for(int i = 0; i < list.length-1; i++){
            if (list[i] == list[counter]){
                continue;
            }
            else{
                counter++;
                uniquesArray[counter] = list[i];
            }   
        }

      return uniquesArray;
}

对于一个值为 { 10, 11, 12 } 的数组,这会返回一个值为 { 10, 11, 0 } 的数组

【问题讨论】:

  • 数组的类型是什么?
  • 是一个double类型的数组。
  • 你可以一次完成,但最终数组大小直到完成后才知道(显然),并且在 java 中数组具有固定大小。这意味着虽然您可以一次性完成重复数据删除和复制,但最终数组必须在重复数据删除之后复制 到正确大小的数组。复制过程需要完整传递,尽管是最终值。这是允许的吗?如果不是,返回 List 是否可以接受?
  • 这是有道理的。这个函数实际上链接到一个函数,该函数确定同一数组中唯一元素的数量,所以我应该能够事先创建一个正确大小的数组。我只是很难弄清楚如何将唯一值设置为新数组的正确索引。到目前为止,我已经得到了很多“几乎”,由于某种原因,新数组的最后一个或第一个索引往往为 0。
  • 如果您有像[1,1,2,2,2,3,4,5,5] 这样的排序数组,您需要将第一个元素添加到新数组并记住您添加到新数组的最后一个值。如果您记住的值与排序数组中的下一个值相同,则跳过它。 Oldarray[0] = 1,newaaray[0] = 1,记住 = 1; oldarray[1] = 1, oldarray == 记住 -> 跳过它。我希望你能明白我在说什么。

标签: java arrays duplicates unique


【解决方案1】:

将值添加(通过List 迭代)到Set,然后从此Set 创建ListSet 只接受唯一的值 - 重复的总是被丢弃。

【讨论】:

  • 虽然这是一个O(n)的解,但是这种方式使用了O(n)的空间,但是有一个O(1)的空间解(不计算输出数组,这是不可避免的)
【解决方案2】:

由于它是一个数据结构类,我假设您必须只使用数组,试试这个:

public double[] getUniqueItems (double[] array){
        double[] unique = new double[array.length];
        Arrays.sort(array);

        double currentItem = array[0];
        unique[0] = currentItem;

        for(int i = 1; i<array.length;i++){
            if(array[i] != currentItem){
                unique[i] = array[i];
                currentItem = array[i];
            }
        }

        return unique;
    }

【讨论】:

  • 数组已经排序。此外,输出可能包含重复项(我会留给您找出原因)
  • 不幸的是,这个似乎不太好用。如果我传入一个 {1, 2, 3, 4, 4} 的数组,它会传回一个 {1, 2, 3, 4, 0} 的数组。
  • for(int i= 1,j = 1; i
【解决方案3】:

不确定您的作业是否允许,但您可以使用 Java 8 oneliner 做您想做的事(完全没有循环):

    double[] dA = ..... // your input array
    Arrays.sort(dA);    // sort it
    double[] dB = IntStream.range(0, dA.length)
                    .mapToDouble(i -> dA[i]).distinct().toArray();

编辑:正如 Bohemian 所指出的,这可以缩短为:

    double[] dB = DoubleStream.of(dA).distinct().toArray();

【讨论】:

  • 感谢您的意见,罗宾。不幸的是,我们不允许调用任何其他函数。这真是令人头疼!不过,我会牢记您的解决方案,以备不时之需。
【解决方案4】:

感谢所有精彩的回复,女士们和伙计们!我考虑了你们每个人所说的很多内容,我相信我已经解决了问题。这是我的解决方案(numUnique 是一个返回排序数组中唯一项数的函数):

public static double[] removeDuplicates (double[] list) {

    int numOfUniques = numUnique(list);
    if (numOfUniques == 0){
        return null;
    }
    else if (list.length < 2){
        return list;
    }


    double[] unique = new double[numOfUniques];
    double currentItem = list[0];
    unique[0] = currentItem;
    int j = 1;

    for (int i = 1; i < list.length; i++){
        if (currentItem != list[i]){
            unique[j] = list[i];
            currentItem = list[i];
            j++;
        }
    }

    return unique;
}

【讨论】:

    【解决方案5】:

    JDK 提供了一个简单的(尽管 O(n) 空间复杂度)解决方案,只使用一次传递:

    return DoubleStream.of(input).distinct().toArray();
    

    如果您需要滚动自己的实现,请考虑由于输入已排序,您只需要保留与前一个元素(加上第一个元素)不同的元素。

    一种实现可能是:

    double[] input; // given this
    int count = 0;
    for (int i = 0; i < input.length; i++) {
        if (i > 0 && input[i] != input[i-1])
            count++;
        input[count] = input[i];
    }
    return Arrays.copyOf(input, count);
    

    这使用结果数组的就地构建,因此仅使用 O(1) 空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-17
      • 2023-03-21
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      相关资源
      最近更新 更多