问题描述
给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。
示例
输入: [3,0,1]
输出: 2
输入: [9,6,4,2,3,5,7,0,1]
输出: 8
说明:
你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现?
思路
这题首先就想到了用数学方法来做。
一共0-n, n+1个数,缺一个。
对数组进行求和,然后计算出来不缺的时候的和,即0~n求和,然后这个和减去数组的和就OK了。(方法一)
这题还有骚玩法,看官方题解:
依照惯例,官方题解总有你看不懂的地方的。就比如为毛把初始值设置为n。
咱们重点就来巴拉巴拉为啥把初始值设为n的问题。
我们这题之所以用异或来做,是因为我们吃准了异或的一个特性:异或同一个数两次相当于没有异或。
这道题,数组的下标范围是0~n-1
,没有遗漏。 数值的范围是0~n
,有遗漏。
我们如果把初始值设置为n,则数组的下标范围可以被认为是扩充到了0~n
, 没有遗漏,而数值的范围是0~n
,有遗漏。 现在问题转化成了,在这一共2n+1
个数中,有一个是不成双成对的。把这个数全部异或一遍剩下的就是那个落单的。(方法二)
方法一
Java版
class Solution {
public int missingNumber(int[] nums) {
int sum = 0;
for(int i = 0; i < nums.length; i++){
sum += nums[i];
}
int originSum = nums.length*(nums.length+1)/2;
return originSum - sum;
}
}
方法二
Java版
class Solution {
public int missingNumber(int[] nums) {
int res = nums.length;
for(int i = 0; i < nums.length; i++){
res ^= nums[i]^i;
}
return res;
}
}