一、题目
面试题 17.04. 消失的数字 - 力扣(LeetCode)https://leetcode.cn/problems/missing-number-lcci/
二、解答
Note:一道题有多种解法,那么我们不用实现,只需要分析出每种方法的复杂度,选择复杂度优的方式即可,这样就是复杂度在实际中的意义。
思路1:排序
先把数组排序,排完序后从小到大遍历,看后一个数是不是前一个数加一,如果不是,返回前一个数加1。
但是排序时间消耗太大,即使用快排进行排序,快排的时间复杂度为,不符合题意。
思路2:数学公式
通过高斯求和公式,从0到n的全部整数之和为。
通过循环计算,得出nums数组的所有值之和为sum。
二者相减,即可得到消失的数字。
时间复杂度,符合题意。
int missingNumber(int* nums, int numsSize)
{
int sum = 0;
for (int i = 0; i < numsSize; ++i)
{
sum += nums[i];
}
return (numsSize + 1) * numsSize / 2 - sum;
}
思路3:建立数组
建立空间大小n+1的数组,nums数组中值是几就在第几个位置上写一下这个值,缺少的那个值就是消失的数字。
空间复杂度O(N) 时间复杂度O(N)
思路4:异或
异或,给一个值x=0;X先跟0-n的所有值异或,x再跟数组中的每个值异或,最后x就是缺的那个数字
两个相同的数异或就异或没了;并且异或的特性不需要考虑它们的顺序
1 2 1 2 3
1 3 2 2 1
以上两个数组分别异或完了之后结果都是3,因为相同的数异或就没了(满足交换律),拿一个变量去跟他们异或,这个变量给值为0,因为0跟任何一个数异或还是这个值
时间复杂度O(N) 空间复杂度O(1)
int missingNumber(int* nums, int numsSize){
int x=0;
for(int i=0;i<=numsSize;++i){
x^=i;
}
for(int i=0;i<numsSize;++i){
x^=nums[i];
}
return x;
}