来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/missing-number-lcci/
数组
nums
包含从0
到n
的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
- 示例一:
输入:[3, 0, 1]
输出:2
- 示例二:
输入:[9, 6, 4, 2, 3, 5, 7, 0, 1]
输入:8
如案例所示,给我们的数组可以是无序的,而这种方法的思路就是先对无序数组进行排序(这里使用的是冒泡排序)得到一个有序数组。使用if语句判断前一个数加1是否等于后一个数,若不等于则代表有缺失的数,那么nums[z]+1就是我们要找的数,返回即可。
#include
int missingNumber(int* nums, int numsSize) {
int tmp = 0; //中间数-用于交换
//数组排序——冒泡排序思想
for (int i = 0; i < numsSize - 1; i++)
{
for (int j = 0; j < numsSize - i - 1; j++)
{
if (nums[j] > nums[j + 1])
{
int temp = nums[j + 1];
nums[j + 1] = nums[j];
nums[j] = temp;
}
}
}
//找出缺失的数——前一个数++是否等于后一个数
for (int z = 0; z < numsSize; z++)
{
if (nums[z] + 1 != nums[z + 1])
{
return nums[z] + 1;
}
}
return 0;
}
但是这种方法存在缺陷,这种方法可在visual studio上测试出来,但是在leetcode上却提交不过去。这种方法不符合时间复杂度的要求,即使使用的是快速排序也需要O(N*logN)的时间复杂度。故这种方法不是最优方法。
这个方法的思路为:缺失的数 = 完整数组之和 - 缺失数组之和
int missingNumber(int* nums, int numsSize)
{
int sum = 0;
for(int i = 0;i
完整数组是一个等差数列,其求和即为等差数列求和。
按位异或是C语言的一个操作符,它的讲解可以看这一篇文章:【C语言】操作符总结(一)
按位异或的规则是:相同为0,相异为1。由此可知:两个相同的数异或到一起就变成0了。例如3与3进行异或:
00000000 00000000 00000000 00000011 —3
00000000 00000000 00000000 00000011 —3
3^3
00000000 00000000 00000000 00000000
因此我们可以让0-n的数字和数组内的数字全部放在一起异或,并且异或满足交换律,即:
0 ^ 1 ^ 2 ^ 3 ^ 3 ^ 0 ^ 1 等价于 0 ^ 0 ^ 1 ^ 1 ^ 3 ^ 3 ^ 2
我们前面说到相同的数异或得到0,即最后为0^2 = 2,得到缺失的数为2。
int missingNumber(int* nums, int numsSize)
{
int ret = 0;
for (int i = 0; i < numsSize + 1; i++)
{
ret ^= i;
}
for (int i = 0; i < numsSize; i++)
{
ret ^= nums[i];
}
return ret;
}