题目:
数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
示例 1:
输入:[3,0,1]
输出:2
示例2:
输入:[9,6,4,2,3,5,7,0,1]
输出:8
使用C语言时LeetCode给出的模板为:
int missingNumber(int* nums, int numsSize){
}
我一共想到了三种方法,但是第一个方法的时间复杂度为O(n*log2 N):
方法一:
由于输入的内容是0-n的,但是有没有按顺序我们不知道,取决于输入的数据。可以先使用qsort函数将它们先排序,然后使用循环一个一个查找就行。
代码实现:
//方法一:排序,然后循环查找。但是时间复杂度通不过 # include# include int cmp(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } int main(void) { int nums[9] = { 0 }; //赋值 for (int i = 0; i < 9; i++) { scanf("%d", nums + i); } //排序 qsort(nums, 9, sizeof(nums[0]), cmp); int ret = missingNumber(nums, 9); printf("%dn", ret); return 0; } int missingNumber(int* nums, int numsSize) { int i = 0; for (i = 0; i < numsSize; ++i) { //如果不匹配,则返回i.就是消失的那个数字 if (*(nums + i) != i) { return i; } } }
方法二:
由于是0-n的数字,少了一个m。
消失的数字 = 没有少数字之前的和 - 少了数字之后的和
//第二种方法 //消失的数字 = 没有少数字之前的和 - 少了数字之后的和 # includeint missingNumber(int* nums, int numsSize); int main(void) { int nums[9] = { 0 }; //对数组赋值 for (int i = 0; i < 9; i++) { scanf("%d", nums + i); } int ret = missingNumber(nums, 9); printf("%dn", ret); return 0; } int missingNumber(int* nums, int numsSize) { int i = 0; int sum1 = 0; int sum2 = 0; //求出少了数字之后的和 for (i = 0; i < numsSize; ++i) { sum1 += *(nums = i); } //求出没少之前的数字之和 for (int i = 0; i <= numsSize; ++i) { sum2 += i; } return sum2 - sum1; }
方法三
第三种方法采用了异或的一些性质:
假如有一个数为a和b,则:
a ^ a = 0
0 ^ a = a; //一个数和0异或得到的是本身
a ^ b ^ c = a ^ c ^ b; //可以进行交换位置·
没有少数字之前,整个数组就是0~n的数字
所以我们让没少数字之前的数组值全部异或,为什么要这样呢?
代码实现:
//使用异或
int missingNumber(int* nums, int numsSize) {
int sum = 0;
for (int i = 0; i < numsSize; i++)
{
sum ^= i;
sum ^= *(nums + i);
}
sum ^= numsSize;
return sum;
}



