查找数组中缺少的数字

时间:2012-09-13 09:25:28

标签: algorithm

数组a[]包含从0到N的所有整数,除了一个。但是,您无法通过单个操作访问元素。相反,您可以调用get(i, k)来返回a[i]的第k位,或者您可以调用swap(i, j)来交换a[]的第i个和第j个元素。设计O(N)算法以找到缺失的整数。 (为简单起见,假设N是2的幂。)

6 个答案:

答案 0 :(得分:9)

如果N是2的幂,则可以使用divide and conquerO(N)中完成。

请注意,数字中有logN位。现在,使用此信息 - 您可以结合使用partition based selection algorithmradix-sort

  1. 迭代第一位的数字,并将数组除以2 一半 - 前半部分将此位设为0,另一半将其设为1.(使用swap()对数组进行分区)。
  2. 请注意,一半有ceil(N/2)元素,另一半有floor(N/2)元素。
  3. 对较小的数组重复此过程,直到找到丢失的数组 号。
  4. 此方法的复杂性为N + N/2 + N/4 + ... + 1 < 2N,因此为O(n)

答案 1 :(得分:3)

O(N * M),其中M是位数:

N是2的幂,只有一个数字丢失,所以如果你检查每一位,并计算该位为0的数字,并计算where为1,你将获得2 ^(M-1)和2 ^(M-1)-1,较短的一个属于缺失的数字。有了这个,你可以得到所有缺失的数字。

答案 2 :(得分:1)

甚至没有必要使用交换操作!! 使用异或! 好的,首先你可以计算从0到N的所有数字的二进制XOR。 首先是:

long nxor = 0;
for (long i = 0; i <= N; i++)
    nxor = XOR(nxor, i);

然后我们可以计算数组中所有数字的XOR,它也很简单。我们称之为K - 所有数字内的最大位数。

long axor = 0;

long K = 0;
long H = N;
while (H > 0)
{
   H >>= 1; K++;
}

for (long i = 0; i < N - 1; i++)
   for (long j = 0; j < K; k++)
    axor = XOR(axor, get(i,j) << j);

最后,您可以计算结果的XOR:

long result = XOR(nxor, axor).

顺便说一句,如果n是2的幂,则nxor值将等于n; - )!

答案 3 :(得分:0)

当我们使用sum运算而不是xor运算时,你也是另一个anwer。 请在下面找到代码。

long allsum = n * (n + 1) / 2;
long sum = 0;

long K = 0;
long H = N;
while (H > 0)
{
   H >>= 1; K++;
}

for (long i = 0; i < N - 1; i++)
   for (long j = 0; j < K; k++)
    sum += get(i,j) << j;

long result = allsum - sum.

答案 4 :(得分:0)

假设输入为a[]=0,1,2,3,4,5,7,8,因此缺少6。这些数字仅为方便起见而排序,因为无需对它们进行排序以使解决方案正常工作。

由于N8,因此数字使用4位表示。 从00001000

首先使用最高位对数组进行分区。

您获得0,1,2,3,4,5,78。由于存在8,请继续使用左侧分区。

使用第二个最重要的位对子数组进行分区。

您获得0,1,2,34,5,7。现在继续使用具有奇数个元素的分区,即4,5,7

使用第3个最高位对子数组进行分区。

您获得4,57。再次继续使用具有奇数个元素的分区,即7

使用第4个最重要的位对nothing7分区子数组。

所以缺少的号码是6

另一个例子:

  • a[]=0,1,3,4,5,6,7,8,因此2缺失。
  • 第1位分区:0,1,3,4,5,6,78,继续0,1,3,4,5,6,7
  • 第二位分区:0,1,34,5,6,7,继续0,1,3(奇数个元素)。
  • 第3位分区:0,13,继续3(奇数个元素)。
  • 第4位分区:nothing3,因此缺少2

另一个例子:

  • a[]=1,2,3,4,5,6,7,8,因此0缺失。
  • 第1位分区:1,2,3,4,5,6,78,继续1,2,3,4,5,6,7
  • 第二位分区:1,2,34,5,6,7,继续1,2,3(奇数个元素)。
  • 第3位分区:12,3,继续1(奇数个元素)。
  • 第4位分区:nothing1,因此缺少0

第一个分区需要N个操作。 第二个分区执行N次操作。 第3个分区执行N/2次操作。 第4个分区需要N/4个操作。 等等。

因此运行时间为O(N + N + N / 2 + N / 4 + ...)= O(N)。

答案 5 :(得分:0)

如果执行xor操作,我们将以这种方式回答此问题

package missingnumberinarray;
public class MissingNumber 
{
    public static void main(String args[])
    {
        int array1[] = {1,2,3,4,6,7,8,9,10}; // we need sort the array first.
        System.out.println(array1[array1.length-1]);
        int n = array1[array1.length-1];
        int total = (n*(n+1))/2;
        System.out.println(total);
        int arraysum = 0;
        for(int i = 0; i < array1.length; i++)
        {
            arraysum += array1[i];
        }
        System.out.println(arraysum);
        int mis = total-arraysum;
        System.out.println("The missing number in array is "+mis);
    }
}