在整数数组中查找缺少的整数

时间:2015-11-28 03:36:24

标签: java bit-manipulation

我最近浏览了一本编码书并遇到了这个有趣的问题。

数组A包含从0到n的所有整数,除了一个数字 失踪。在这个问题中,我们无法通过单个操作访问A中的整个整数。 A的元素以二进制表示,是我们可以使用的唯一操作 访问它们是“获取A [i]的第j位”,这需要恒定的时间。写代码 找到缺少的整数。你能在0(n)时间内完成吗?

本书的作用是通过一个三页的过程来解释如何有效地完成这个问题。说实话,它有点TL; DR对我来说,所以我自己做了解决方案并将它与书的比较。我只是想知道我的解决方案是否真的有效(因为看起来怀疑这本书的答案可以如此长而详细,只需几分钟即可完成更简单的解决方案。)

这是本书的解决方案:

 1 public int findMissing(ArrayList<BitInteger> array) {
 2     /* Start from the least significant bit, and work our way up */
 3     return findMissing(array, 0);
 4 }
 5
 6 public int findMissing(ArrayList<BitInteger> input, int column) {
 7     if (column >= BitInteger.INTEGER_SIZE) { // We're done!
 8         return 0;
 9     }
10     ArrayList<BitInteger> oneBits =
11         new ArrayList<BitInteger>(input.size()/2);
12     ArrayList<BitInteger> zeroBits =
13         new ArrayList<BitInteger>(input.size()/2);
14
15     for (BitInteger t : input) {
16         if (t.fetch(column) == 0) {
17             zeroBits.add(t);
18         } else {
19             oneBits.add(t);
20         }
21     }
22     if (zeroBits. size() <= oneBits.size()) {
23         int v = findMissing(zeroBits, column + 1);
24         return (v « 1) | 0;
25     } else {
26         int v = findMissing(oneBits, column + 1);
27         return (v « 1) | 1;
28     }
29 }

我自己的解决方案对我来说似乎是相同的O(n)时间复杂度,但是在O(1)空间复杂度的情况下完成,要简单得多。我将“fetch”方法定义为接受两个参数。第一个指定第x位,第二个指定索引号。我假设这个方法是给定的,因为它在问题中被提到(“获取A [i]的第j位”)。基本上,我只是检查最低位是否在1和0之间交替 - 这就是它的全部内容。

int findMissing(int[] arr) {
    int lowBit = fetch(0, 0); // fetch the 0th bit of arr[0]
    if(lowBit != 0) {
        return 0; // obviously, the array is not starting at 0, so 0 must be what is removed
    }
    int expectedNextBit = 1; // we expect the lowest bit to be 1
    for(int x = 1; x < arr.length; x++) {
        lowBit = fetch(0, x); // fetch the 0th bit (lowest) of arr[x]
        if(lowBit != expectedNextBit) {
            return x;
        }
        expectedNextBit = lowBit ^ 0x1;
    }
    return arr.length;
}

我的问题是 - 我自己的解决方案有什么问题?我是大二学生本科生,这本书是由博士写的,所以我非常怀疑我的答案实际上可能比他们好。

2 个答案:

答案 0 :(得分:1)

您的解决方案错误地假定输入数字已排序。如果您的输入为[0, 2, 1, 3, 5],则您的解决方案会错误地报告1,即使它稍后出现在数组中。

答案 1 :(得分:0)

  

我自己的解决方案出了什么问题?

您的源代码的第一件事是错误的:
提供的源代码未说明要完成的任务。

没有理由使用特殊情况下的索引Id=6(还有一个很好的理由不这样做:如果0会怎样?)。

0 == arr.length可能仅显示:

findMissing()