题目
给定一个包含 0, 1, 2, ..., n
中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。
来源:https://leetcode-cn.com/problems/missing-number/
示例 1:
输入: [3,0,1]
输出: 2
示例 2:
输入: [9,6,4,2,3,5,7,0,1]
输出: 8
额外要求:
你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现?
解答
方法一:
在不考虑线性时间复杂度的前提下,使用排序,然后查找的方法可以解决。我也就能想到这方法,后边的方法二和方法三
实在是想不到,太巧妙了。
class Solution {
public:
int missingNumber(vector<int>& nums) {
std::sort(nums.begin(), nums.end());
if (nums.front() != 0) {
return 0;
}
if (nums.back() != nums.size() ) {
return nums.size();
}
for (int i = 0; i < nums.size() - 1; ++i) {
if (nums[i] + 1 != nums[i + 1]) {
return nums[i] + 1;
}
}
return 0;
}
};
方法二:
思路是:
- 求0-n和然后减去数组的和就是答案
- 防止溢出,可以在加的同时进行减操作
class Solution {
public:
int missingNumber(vector<int>& nums) {
int sum = 0;
/// 最大的数字为 nums.size()
/// 把 0 到 nums.size() + 1全部加一起来
for (int i = 0; i < nums.size(); i++) {
sum = sum + i - nums[i];
}
sum += nums.size();
return sum;
}
};
方法三:
异或法,
- 相同的数异或操作之后是0
- 异或操作之后最终结果就是缺失的那个数字
class Solution {
public:
int missingNumber(vector<int>& nums) {
///用异或抵消
int res = 0;
for (int i = 0; i < nums.size(); ++i) {
res ^= nums[i];
res ^= i;
}
res ^= nums.size();
return res;
}
};