消失的数字
题目描述:数组nums
包含从0
到n
的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
示例 1:
输入:[3,0,1] 输出:2
示例 2:
输入:[9,6,4,2,3,5,7,0,1] 输出:8
思路1:求和相减
(n+1)*n/2 -(数组中所有元素之和)得到的值即为缺失的那个整数。
时间复杂度:O(N)
空间复杂度:O(1)
int miss_Number(int* nums, int n)
{
int i;
int sum1 = 0;
int sum2 = 0;
for (i = 0;i <= n;i++)
{
sum1 += i;
}
for (i = 0;i < n;i++)
{
sum2 += nums[i];
}
return sum1 - sum2;
}
思路2:异或
异或操作是对二进制位进行的,相同二进制位异或结果为0,相异二进制位异或结果为一。表现在整体上有,相同整数异或结果为0,因为每个二进制位对应相等所以每个二进制位异或的结果都为零,因此整体表现为0。还可以知道一个整数与0异或结果还是这个整数本身。
此外异或遵循交换律和结合律。例如3^5^3=5,等同于(3^3)^5 = 0^5 = 5
利用以上性质,可以先将0~N的数字全部异或一遍,因为异或具有交换律因此不用考虑数字的顺序。再将异或结果与数组中的元素逐个异或一遍。在这个过程中,数组中有的元素在整个过程中出现了两次,而相同数字异或的结果为0,数组中唯一缺失的那个数字与0异或结果为它本身。
时间复杂度:O(N)
空间复杂度:O(1)
int miss_Number(int* nums, int n)
{
int N = numSize;
int x = 0;
for (int i = 0;i < numSize;++i)
{
x ^= nums[i];
}
for (size_t j = 0;j < N + 1;++j)
{
x ^= j;
}
return x;
}