1. 🎈题目
2. 🎈解题思路
✨方法一:先排序,再找缺失的值
1.先用冒泡排序将数组排成有序的。
2.遍历每个元素,判断+1后是否等于后面一个元素。如果不等于,则+1后得到得数字就是缺失的数字。因为要遍历N(未知)次,所以O(N)
》整体时间复杂度为最高阶项O(N^2)。
✨方法二:按位异或,找缺失的值
对于整数a:
a ^ a ==0
;0 ^ a == a
;(支持分配律)
1.让0 ^ 数组中的每个数,再 ^ 数字1~n。在这个式子里,数组中未缺少的数会有两个,按位异或得0;缺少的只有一个,与0按位异或后就得出了这个缺少的数。
》因为会进行N(未知)次 ^ 操作,所以时间复杂度为O(N)
✨方法三:相减,找缺失的值
1.将1~n个数相加得到和sum
2.用sum 减去数组中的元素,得到的就是数组中缺少的元素
》因为出现了N(未知)次减元素的操作,所以时间复杂度为O(N)
3.🎈具体代码
方法一:
//时间复杂度O(n^2)
int missingNumber(int* nums, int numsSize) {
//冒泡排序
int i = 0;
for (i = 0; i < numsSize - 1; ++i)
{
int j = 0;
for (j = 0; j < numsSize - 1 - i; ++j)
{
if (nums[j] > nums[j + 1])
{
int tmp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = tmp;
}
}
}
//判断前面的数+1是否 == 后面的数
for (i = 0; i < numsSize - 1; ++i)//比较numsSize-1次,判断前面的数+1是否 == 后面的数
{
if (0 != nums[0])//如果第一个数不是0,则说明缺少0
{
break;
}
if (nums[i] + 1 == nums[i + 1])//不严谨,第1的数不是0时,条件也都成立
{
continue;
}
else
{
break;
}
}
if (0 != nums[0])
{
return 0;
}
else
{
return nums[i] + 1;
}
}
方法二:
//时间复杂度O(n)
int missingNumber(int* nums, int numsSize) {
//两个相同的数按位异或,得0; 0 ^ a == a
//举例:0^1^2^1 == 2
int x = 0;
int i = 0;
for (i = 0; i < numsSize; ++i)//0~n中少了一个数,所以共n个数
{
x ^= nums[i];
}
for (i = 0; i <= numsSize; ++i)//按位异或 从0 到 n的数
{
x ^= i;
}
return x;
}
方法三:
//时间复杂度O(n)
int missingNumber(int* nums, int numsSize) {
//计算0~n个数的和(等差数列,差为1)
//0~n共 numsSize+1个数,所以n == numsSize
int sum = (0 + numsSize) * (numsSize + 1) / 2;
//计算nums中元素的和
int i = 0;
int sum2 = 0;
for (i = 0; i < numsSize; ++i)
{
sum2 += nums[i];
}
return sum - sum2;
}
🎇总结
本篇文章我们用三种方法,逐渐减少时间复杂度,解决了力扣上消失的数字这道题,感谢大家的阅读!大家一起进步!
点赞收藏加关注,C语言学习不迷路!