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

数组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)空间复杂度完成)要简单得多。我将“获取”方法定义为采用两个参数。第一个指定第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;
}


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

最佳答案

您的解决方案错误地假定输入数字已排序。如果输入的是[0, 2, 1, 3, 5],则解决方案将错误地报告1,即使它出现在阵列的后面。

关于java - 在整数数组中查找缺失的整数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33967374/

10-16 15:58