题目
本题我不使用hash表法。。因为hash表实在是太没技术含量了。。
解法一:强行排序双指针
class Solution {
public:
int missingNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
int n = nums.size();
int l = 0,r = nums.size()-1;
int res = 0;
//排除两个缺失数字在最左和最右的特殊情况。
if(nums[n-1]!=n)return n;
if(nums[0]!=0)return 0;
//当排序后的两个相邻的数字相差超过1,则得出答案。。
while(l<r){
if(l+1<r&&(nums[l+1]-nums[l])==1)
l++;
else {res = nums[l]+1;break;}
if(r-1>l&&(nums[r]-nums[r-1])==1)
r--;
else{res = nums[r]-1;break;}
}
return res;
}
};
解法二:数学求和公式法
很明显的等差数列求和。。
sum = (0+n)*n+1/2.(首项+末项)x项数/2
class Solution {
public:
int missingNumber(vector<int>& nums) {
int n = nums.size();
long long sum = n*(n+1)/2;
for(int i=0;i<n;i++){
sum -= nums[i];
}
return sum;
}
};
解法三:位运算
这次位运算并不是大爹–还是O(n)的复杂度。
具体思路:由于本身是0~n的数字都只出现了一次,我们现在将其中一数字缺失,如果并未缺失我们对0到n序列和0到n序列进行异或运算,则最终结果肯定是0,若我们中只缺失了那一个,则结果便会是那个数字了。
代码
class Solution {
public:
int missingNumber(vector<int>& nums) {
int n = nums.size();
int res = 0;
for(int i=0;i<n;i++){
//相当于实现0^0...n^0...n,但少了n所以最后再补上。
res ^= nums[i]^i;
}
return res^n;
}
};