【问题标题】:Finding missing number(s) from an array从数组中查找缺失的数字
【发布时间】:2016-04-15 10:17:36
【问题描述】:

编写此代码,希望获得更好的方法,使用任何算法从已排序或未排序的数组中查找缺失的数字。如果它是一个未排序的数组,我将排序并执行以下操作。

private static void identifyMissingValues(Integer[] ar) {

        for(int i = 0; i < (ar.length - 1); i++) {

            int next = ar[i + 1];
            int current = ar[i];
            if((next - current) > 1) {
                System.out.println("Missing Value : " + (current + 1));
            }
        }
    }

任何比这更快或更好的代码,请提出建议。

【问题讨论】:

  • 如果序列中只缺少一个数字,您可以将您拥有的所有 nubers 相加,将整个预期序列相加,然后从另一个和中减去一个和以获得缺少的数字
  • 如果连续有两个或多个遗漏,只会打印第一个

标签: java arrays algorithm missing-data


【解决方案1】:

任何比这更快或更好的代码,请提出建议。

没有这样的事情 - 如果必须访问每个元素,您就无法改进 O(n) 算法。

【讨论】:

  • 我们可以用除 O(n) 算法之外的任何其他方式重写代码来查找多个缺失值吗?
  • @srikanth - 是的 - 但效率会降低。
【解决方案2】:

使用 BitSet 代替排序。

    int[] ar = {7, 2, 6, 8, 10, 4, 3, 2};
    int min = IntStream.of(ar).min().getAsInt();
    BitSet b = new BitSet();
    for (int i : ar)
        b.set(i - min);
    int i = 0;
    while ((i = b.nextClearBit(i + 1)) < b.length())
        System.out.println(i + min);

结果

5
9

【讨论】:

    【解决方案3】:

    对数组进行排序需要O(n*log(n))

    如果将数组的所有元素添加到 HashSet (O(n)) 运行时间,然后检查 0ar.length - 1(或任何相关范围)之间的每个数字是否HashSet 包含该号码。这需要O(n) 时间。

    【讨论】:

    • 但是你为什么要排序呢?
    • @MrD 我不想对它进行排序 - OP 可以(If its an unsorted array, i would sort and execute the following.)。这就是为什么我提供了一个不需要排序的替代方案。
    • @Eran 使用 HashSet 即时间复杂度 (O(n)) 对于更大的数据集总是更好地执行。对吗?
    【解决方案4】:

    您的方法很好,但我添加了更多内容,因为缺少一个以上的数字..

    eg : ar={1,2,4,6,10} // Sorted Array
    
    private static void identifyMissingValues(Integer[] ar) {
        for (int i = 0; i < (ar.length - 1); i++) {
            int next = ar[i + 1];
            int current = ar[i];
            if ((next - current) > 1) {
                for (int ind = 1; ind < next - current; ind++)
                    System.out.println("Missing Value : " + (current + ind));
            }
        }
    }
    

    输出是,

    Missing Value : 3
    Missing Value : 5
    Missing Value : 7
    Missing Value : 8
    Missing Value : 9
    

    【讨论】:

    • 输出必须是3 5 7 8 9
    【解决方案5】:

    我可以知道输入和预期输出的数字系列吗?
    根据您的代码,我觉得系列应该相差 1,如果我没记错的话。

    【讨论】:

    • 这不是答案。它应该像评论一样发布。
    【解决方案6】:

    所以你有一个由 n 个元素组成的数组,它以整数 i 开头并包含从 i 到 i+n 的所有整数,对吗?例如:

    arr = [1,2,3,4,5]
    

    所以,数组中所有数字的和应该是从 i 到 i+n 的数字之和。

    例如:sum(arr) = 1+2+3+4+5 = 15

    数字1到n之和的公式是n(n+1)/2

    所以你可以有一个for循环:

    int counter = 0;
    
    for(Integer i : integers)
        counter += i
    

    获取数组中数字的总和。

    如果您的数组从 1 开始,则检查 counter 变量是否等于 n(n+1)/2,其中 n 是数组的长度。

    如果您的数组不是从一个开始,例如arr = [78, 79, 80, 81],那么您需要稍微调整一下这种方法,但我相信您可以解决。

    【讨论】:

    • 该算法如何告诉您缺少哪些数字? (除非只缺少一个数字,根据问题中的代码似乎并非如此)。
    【解决方案7】:

    你可以这样做:

    Set<Integer> mySet = new TreeSet<Integer>(Arrays.asList(ar));
    int min = mySet.first();
    
    for (int i = 0; i < mySet.size(); i++) {
        int number = min + i;
        if (!mySet.contains(number)) {
            System.out.println ("Missing: " + number);
            i--;
        }
    }
    

    【讨论】:

      【解决方案8】:
      Integer [] list = new Integer[]{1, 12, 85, 6, 10};
      
      
      Integer previous = null;
      
      
      Arrays.sort(list);
      
      System.out.println(list);
      
      
      for(int index = 0; index < list.length; index++){
      
      
         if(previous == null){
             previous = (Integer) list[index];
             continue;
         }
      
          Integer next = previous + 1;
          if(((Integer) list[index] - previous) > 1){
      
              System.out.println("Missing value " + next);
              index--;
      
          }
          previous = next;
      
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-12-03
        • 1970-01-01
        • 2011-11-11
        • 2017-11-07
        • 1970-01-01
        • 1970-01-01
        • 2014-09-08
        相关资源
        最近更新 更多