题目:
Given an array containing n distinct numbers taken from 0, 1, 2, ..., n
, find the one that is missing from the array.
For example,
Given nums = [0, 1, 3]
return 2
.
Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
思路:
1、求和法:个人感觉这个解法也是完全符合题目要求的,首先用高斯求和法求出1-n之间的所有数字的和,然后依次减去nums中的每一个数,剩余的那个数就是miss掉的数。
2、异或法:还记得那个数组中一个元素出现一次,其余元素都出现过两次的题目吧?这道题目稍微转换一下就是那道题目:如果我们把nums中的索引加进去一起进行异或,那么就相当于除了miss掉的那个数之外,其余数都出现了两次。所以我们将所有索引以及所有nums中的数异或一遍,结果即为所求。是不是非常巧妙的思路转换?
3、置换法:假如允许对nums进行修改,我们可以首先给nums的末尾添加一个0,然后采用类似于桶排序的思路,将nums[i]移到第i个位置。最后再遍历一遍数组,一旦发现nums[i] != i,这说明该位置上的数就是miss掉的数。
代码:
1、求和法:
class Solution {
public:
int missingNumber(vector<int>& nums) {
int len = nums.size();
long long sum = static_cast<long long>(len) * (len + 1) / 2;
for(auto val: nums) {
sum -= val;
}
return static_cast<int>(sum);
}
};
2、异或法:
class Solution {
public:
int missingNumber(vector<int>& nums) {
int result = 0, len = nums.size();
for(int i = 0; i < len; ++i) {
result ^= (i ^ nums[i]);
}
return result ^ len;
}
};
3、置换法:
class Solution {
public:
int missingNumber(vector<int>& nums) {
nums.push_back(0);
int len = nums.size();
for (int i = 0; i < len; ++i) {
while (nums[i] != 0 && nums[i] != i) {
swap(nums[i], nums[nums[i]]);
}
}
for (int i = 0; i < len; ++i) {
if (nums[i] != i) {
return i;
}
}
return 0;
}
};