题目描述
给定一个包含 0, 1, 2, ..., n
中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。
示例 1:
输入: [3,0,1] 输出: 2
示例 2:
输入: [9,6,4,2,3,5,7,0,1] 输出: 8
解法1:求和,线性复杂度/常数空间,注意溢出
class Solution {
public:
int missingNumber(vector<int>& nums) {
int len = nums.size();
long sum = len; //long避免溢出,巧用初始化
//sum(0,1...n) - sum(nums[0,1...n-1])
for (int i = 0; i < len; ++i)
sum += i - nums[i];
//sum += len; //利用len的初始化,免去这一步
return sum;
}
};
解法2:异或,线性复杂度/常数空间
class Solution {
public:
int missingNumber(vector<int>& nums) {
int len = nums.size();
int sum = len;
//sum^(0,1...n)^(nums[0,1...n-1])
for (int i = 0; i < len; ++i)
sum = sum^i^nums[i];
//sum ^= len; //利用len的初始化,免去这一步
return sum;
}
};
解法3:哈希,线性复杂度/线性空间
class Solution {
public:
int missingNumber(vector<int>& nums) {
int len = nums.size();
vector<bool> hash(len+1, false);
int i = 0;
for (; i < len; ++i)
hash[nums[i]] = true;
for (i = 0; i < len+1; ++i)
if (hash[i] == false)
break;
return i;
}
};
解法4:排序遍历,O(nlogn)复杂度/常数空间
class Solution {
public:
int missingNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int len = nums.size();
int i =0;
for (; i < len; ++i) {
if (i != nums[i])
break;
}
return i;
}
};
解法5:排序二分,O(nlogn)复杂度/常数空间
class Solution {
public:
int missingNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int len = nums.size();
int left = 0, right = len-1;
while (left < right) {
int mid = (left + right)>>1;
if (nums[mid]^mid) //nums[mid] != mid
right = mid;
else
left = mid+1;
}
if (left == nums[left])
return left+1;
return left;
}
};