Given numbers from 1 to 2^32-1, one is missing. How to find the missing number optimally?

前端 未结 5 1027
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-14 03:58

You are given 2^32-2 unique numbers that range from 1 to 2^32-1. It\'s impossible to fit all the numbers into memory (thus sorting is not an option). You are asked to find t

相关标签:
5条回答
  • 2020-12-14 04:39

    Add all the numbers you are given up using your favourite big integer library, and subtract that total from the sum of all the numbers from 1 to 2^32-1 as obtained from the sum of arithmetic progression formula

    0 讨论(0)
  • 2020-12-14 05:01

    Use bitwise operator XOR. Here are example in JavaScript:

    var numbers = [6, 2, 4, 5, 7, 1]; //2^3 exclude one, starting from 1
    var result = 0;
    
    //xor all values in numbers
    for (var i = 0, l = numbers.length; i < l; i++) {
        result ^= numbers[i]; 
    }
    
    console.log(result); //3
    
    numbers[0] = 3; //replace 6 with 3
    //same as above in functional style
    result = numbers.reduce(function (previousValue, currentValue, index, array) {return currentValue ^= previousValue;});
    
    console.log(result); //6
    

    The same in C#:

    int[] numbers = {3, 2, 4, 5, 7, 1};
    
    int missing = numbers.Aggregate((result, next) => result ^ next);
    
    Console.WriteLine(missing);
    
    0 讨论(0)
  • 2020-12-14 05:03

    Assuming you can get the Size() you can use some binary approach. Select the set of numbers n where n< 2^32 -2 / 2. then get a count. The missing side should report a lower count. Do the process iteratively then you will get the answer

    0 讨论(0)
  • 2020-12-14 05:03

    If you do not have XOR, then of course you can do the same with ordinary "unchecked" sum, that is sum of 32-bit integers with "wrap around" (no "overflow checking", sometimes known as unchecked context).

    This is addition modulo 232. I will consider the "unsigned" case. If you 32-bit int uses two's complement, it is just the same. (To a mathematician, two's complement is still just addition (and multiplication) modulo 232, we only pick a different canonical representative for each equivalence class modulo 232.)

    If we had had all the non-zero 32-bit integers, we would have:

    1 + 2 + 3 + … + 4294967295 ≡ 2147483648
    

    One way of realizing this is to take the first and the last term together, they give zero (modulo 232). Then the second term (2) and the second-last term (4294967294) also give zero. Thus all terms cancel except the middle one (2147483648) which is then equal to the sum.

    From this equality, imagine you subtract one of the numbers (call it x) on both sides of the symbol. From this, you see that you find the missing number by starting from 2147483648 and subtracting (still unchecked) from that all of the numbers you are given. Then you end up with the missing number:

    missingNumber ≡ 2147483648 - x1 - x2 - x3 - … - x4294967294
    

    Of course, this is the same as moonshadow's solution, just carried out in the ring of integers modulo 232.


    The elegant XOR solution (sykora's answer) can also be written in the same way, and with that XOR functions as both + and - at the same time. That is, if we had all the non-zero 32-bit integers, then

    1 XOR 2 XOR 3 XOR … XOR 4294967295 ≡ 0
    

    and then XOR with the missing number x on both sides of the symbol to see that:

    missingNumber ≡ x1 XOR x2 XOR x3 XOR … XOR x4294967294
    
    0 讨论(0)
  • 2020-12-14 05:04

    Major Edit: Trust me to make things much harder than they have to be.

    XOR all of them.

    I'm assuming here that the numbers are 1 to 232 - 1 inclusive. This should use 1 extra memory location of 32 bits.

    EDIT: I thought I could get away with magic. Ah well.

    Explanation:

    For those who know how Hamming Codes work, it's the same idea.

    Basically, for all numbers from 0 to 2n - 1, there are exactly 2(n - 1) 1s in each bit position of the number. Therefore xoring all those numbers should actually give 0. However, since one number is missing, that particular column will give one, because there's an odd number of ones in that bit position.

    Note: Although I personally prefer the ** operator for exponentiation, I've changed mine to ^ because that's what the OP has used. Don't confuse ^ for xor.

    0 讨论(0)
提交回复
热议问题