Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.

Example 1
Input:
Output: 2

Example 2
Input:
Output: 8
一个“简单”的问题,深思之后似乎并没有那么简单。
最开始的版本:

int missingNumber(int* nums, int numsSize) 
{
    int sum = 0;
    sum = numsSize *(numsSize + 1) / 2;
    for(int i = 0;i < numsSize;i++)
        sum = sum - nums[i];
    
    return sum;
}

程序很简单,1到n的和减去数组的每个元素,最后剩下的值就是缺失的元素。可是这里存在一个溢出的风险,numsSize *(numsSize + 1)可能超出int表示的最大范围,在不改变数据类型的前提下可以采用如下方法:

int missingNumber(int* nums, int numsSize) 
{
    int sum = 0;
    
    if(0 == numsSize % 2)
        sum = numsSize/2 *(numsSize + 1);
    else
        sum = (numsSize + 1)/2 *(numsSize);
        
    for(int i = 0;i < numsSize;i++)
        sum = sum - nums[i];
    
    return sum;
}

另一种方法:

int missingNumber(int* nums, int numsSize) 
{
    int sum = 0;
    int i = 0;
    for(i = 0;i < numsSize;i++)
        sum = sum + i - nums[i];
    
    return sum + i;
}

以上代码均存在溢出风险,采用异或操作可以避免溢出,代码如下:

int missingNumber(int* nums, int numsSize) 
{
    int xor = 0;
    int i = 0;
    for(i = 0;i < numsSize;i++)
        xor = xor ^ i ^ nums[i];
    
    return xor ^ i;
}

异或操作可行性源于两个相同的数字异或为0,因此最后的结果就是缺失的数字,异或的顺序不重要。