题目:
给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。
题目分析:
- 要点:
注意题目中的0~n的数组,可得->遍历时仅需从零遍历到nums.length即可,无需遍历寻找最大最小值 - 对所给的数组进行查找,找到0~n中没有出现的那个数字并进行输出
题目解答:
-
方法一(依次遍历进行查找):
a. 建立两个for循环
b. 依次进行0~n与每个数组进行比较
若遍历结束还没有找到相匹配的值,则输出该数字,该数字便为缺失的数字
若找到,则进行下一个数字的比较 -
方法二(运用数学):
a. 将数组中的数字相加
b. 与0~n的总和进行比较相减
c. 相减得到的数字就是所缺失的数字 -
方法三(运用异或,位运算)
规则:
交换律:a ^ b ^ c <=> a ^ c ^ b
任何数于0异或为任何数 0 ^ n => n
相同的数异或为0: n ^ n => 0a. 0^4=4 ; 4^4=0
b. 将数组中所有的数字和0~n进行异或
代码实现:
- 方法一(遍历):
//遍历判断,找出0~n中没有的那个数字
for(int a=0;a<nums.length;a++){
boolean flag=false; //定义一个指标,用来判断是否为正常结束for循环退出
for(int i=0;i<nums.length;i++){
if(a==nums[i]){
flag=true;
break; //如果相等的话,不用考虑节后的数字,直接进行退出
}
}
if(!flag){
return a;
}
}
return nums.length; //防止出现缺失的数字是最后个数字时的情况
- 方法二(运用数学 —相加相减):
//将所有数字加起来,减去0~n即可得出缺失的数字
int sum=0;
for(int i=0;i<nums.length;i++){
sum+=nums[i];
}
return nums.length*(nums.length+1)/2-sum; //运用数学思维计算总和,返回相减的值
- 方法三(异或—位运算):
//异或 运用位运算
int res=nums.length;
for(int i=0;i<nums.length;i++){
res^=nums[i]^i; //将所有的数组中所有的数字和0~n异或起来
}
return res;
代码总结:
- 方法一:所占用的空间较大,且代码相比其他的方法过多,不推荐使用;
- 方法二:运用数学思维,简化了代码,是运算该种类型的题的简便技巧;
- 方法三:异或——>与136“只出现一次数字”思路较像,推荐。