【问题标题】:Remove duplicates from unsorted array [duplicate]从未排序的数组中删除重复项[重复]
【发布时间】:2016-01-24 22:20:20
【问题描述】:

我从给定的未排序数组中快速返回非重复数组的方法似乎只在某些时候有效:

    public static int[] removeDuplicates(int[] arr) {
    if (arr.length <= 1) {
        return arr;
    }

    int lastFound = arr[0];

    int currPos = 1;
    for (int i = 1; i < arr.length; ++i) {
        int num = arr[i];
        if (lastFound != num) {
            lastFound = num;
            arr[currPos++] = num;
        }
    }

    return Arrays.copyOf(arr, currPos);
}

当我输入时:

int[] arr = {0, 1, 1, 0, 1, 1, 2, 2}
int[] arr2 = removeDuplicates(arr);

它会返回:

arr2 = {0, 1, 0, 1, 2}

它应该返回的位置(没有重复):

arr2 = {0, 1, 2}

【问题讨论】:

  • 你试过调试你的代码吗?
  • 您的算法不正确。对于 input 数组的每个元素,您必须检查 output 数组的所有元素是否该值已经在其中;如果没有,添加到输出数组。 (输出数组是否重用输入数组并不重要。)

标签: java sorting duplicates


【解决方案1】:

为了确定是否添加一个值,您只需要查看前一个元素(或者,更确切地说,是前一个相等值运行中的第一个元素)。

这意味着它仅在具有给定值的所有元素在数组中都是连续的情况下才有效,它们不适用于您的示例输入。

例如它适用于

{0, 0, 1, 1, 2}  // Sorted.

{2, 0, 0, 1, 1}  // Unsorted, but all equal elements are together.

为了使其正常工作,您需要记录您之前见过的所有元素,而不仅仅是上一次运行开始时的元素,例如通过将看到的元素存储在一个集合中。但是,鉴于向集合中添加已经存在的元素不会更改集合,您也可以将整个数组添加到集合中:

LinkedHashSet<Integer> set = new LinkedHashSet<>(Arrays.asList(arr));

set.addAll(Arrays.asList(arr)); // If the set already exists.

如果你想返回一个int[](而不是Integer[],你可以使用set.toArray(new Integer[])),你需要将元素复制回一个数组:

int[] result = new int[set.size()];
int idx = 0;
for (int value : set) {
  result[idx++] = value;
}
return result;

【讨论】:

  • 是否可以在 O(n) 时间和 O(1) 空间内完成?如果是,怎么做?
  • @AnV 您无法调整现有数组的大小,这使得完全就地执行此操作有些困难。您可以将数组元素重新排列到位,然后在最后创建一个新数组;但这在时间上是低效的。这是一种权衡。
  • 是否可以在 O(n) 时间内“就地”重新排列数组元素?我的意思是如果原始 arr 是 [2,1,3,2,1,4] 我们可以将它重新排列为 [2,1,3,4,1,4] 并说大小是 4。
  • @AnV 没有。将评论填充到最小长度。
【解决方案2】:

处理问题的方法是在遍历数组时记录数组中出现的每个元素,并删除重复的元素。记录元素是使用哈希表。

 public int[] removeDups(int[] data){
       Hashtable table = new Hashtable();
       ArrayList<int> arrayList= new ArrayList<int>(Arrays.asList(array));
       for(int i = 0; i < data.length; i++){
           if(table.containsKey(arrayList.get(i)){
          arrayList.remove(i);
      }else{
          table.put(arrayList.get(i),true);
      }
  }
  return arrayList.toArray();

}

这样,删除重复项更容易。

【讨论】:

    【解决方案3】:

    您可以使用一组整数,这将确保您只有唯一的值

    HashSet<Integer> set = new HashSet<Integer>();
    for (int i = 1; i < arr.length; ++i) {
        set.add(arr[i]);
    }
    return set.toArray();
    

    您的方法将适用于排序数组,因此如果您使用合并排序进行排序 数组中的元素将需要 O(n log n) 最坏的情况,您可以遍历数组并排除与数组中前一个相同的任何项目,从而产生一个只有唯一数字的数组。

    public int[] removeDuplicates(int[] data) {
        // Make sure you have elemens in the array and it's not empty
        Arrays.sort(data);
        int number = data[0];
        ArrayList<Integer> result = new ArrayList<Integer>;
        for (int i = 1; i < data.length; ++i) {
            if (data[i] != number) {
                number = data[i];
                result.add(data[i]);
            }
        }
    
        result.toArray();
    }
    

    【讨论】:

      猜你喜欢
      • 2016-10-01
      • 2021-11-12
      • 2021-01-27
      • 2021-12-12
      • 2022-01-03
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多