丢失的数字
注:这一题的解法建立在位运算——异或^的基础之上,如果位运算和异或操作符不太了解,建议先看看:
思路
同样,这题要求时间复杂度为O(n),空间复杂度为O(1)
可能有小伙伴做了找到消失的数字后,也觉得这题也可以用同样的方法,通过改变对应下标的元素来找到丢失的数字。但是我们应该清楚两题的不同点:
- 《找到消失的数字》数组的长度为n,数据范围也只有n个数;《丢失的数字》数组长度为n,但数据范围却有n + 1个数
- 由于上面的不同,《找到消失的数字》可以通过
数据绝对值-1
的方法来确定一个唯一的下标进行修改,从而达到目标;而《丢失的数字》无法通过数组数据来确定一个唯一的下标- 《找到消失的数字》数组中的元素可以重复;《丢失的数字》数组中的元素独一无二
这一题,我们同样利用异或的特性解决问题
异或的特性:
异或是支持交换律的:
a ^ b ^ c
=b ^ a ^ c
a ^ a = 0
(相同的数异或为0)
0 ^ a = a
(一个数和0异或得到的还是本身)
由于数组元素范围都在[0,n]
但少了[0,n]
的一个数,那么我们就可以将[0,n]
的每一个数异或到一起,再将这个结果和数组中的每个元素异或到一起,那么最后得到的就是这个丢失的数字。
实现代码
int missingNumber(int* nums, int numsSize){
int ret = 0; //设置返回值
//将数组的每个元素异或到一起
for(int i = 0; i < numsSize; i++)
ret ^= nums[i];
//将[0,n]的每个数据异或到一起
for(int i = 0; i <= numsSize; i++)
ret ^= i;
return ret;
}
可能又有小伙伴回想为什么找到消失的数字不能用异或法,这是因为**《找到消失的数字》数组中的数据可以重复,这就导致了消失的数字就不止一个,而用异或只能确定一个数字,**因此异或法就行不通了。