Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.
Example 1
Input: [3,0,1]
Output: 2
Example 2
Input: [9,6,4,2,3,5,7,0,1]
Output: 8
给定一个数组,数组的长度为n,其中的数字本来应该是0到n,但是数组长度为n那么就会缺失了一个数字(因为0到n是n+1个数字),找到其中缺失的数字。
第一个可以利用排序,排序完成之后看一看当前的数字加上一之后是否等于后面的一个数字,如果不等于的说则说明后面的数字缺失了。但是需要注意的是,测试数组有可能只给一个数,所以需要单独对比最开始的和最后的数字。
class Solution {
public:
int missingNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());//进行排序
if(nums[0] != 0) {//如果第一个数字不等于0
return 0;
}
if(nums[nums.size()-1] != nums.size()) {//如果最后一个数字不等于数组的长度
return nums.size();
}
for(int i=1;i<nums.size();i++) {
if(nums[i-1]+1 != nums[i]) {//如果前面的的加上一之后与当前的一位不相等,则说明缺失了
return nums[i-1] + 1;
}
}
}
};
第二可以利用哈希表,将数组的内容放到哈希表中,并且将value对应的值加一。然后从0到n开始遍历,查找哪一个数字没有加一,就是那个缺少的数字。
class Solution {
public:
int missingNumber(vector<int>& nums) {
unordered_map<int,int> numSet;
for(int i=0; i<nums.size(); i++) {//遍历数组,将其内容放到哈希表中
numSet[nums[i]]++;//对应的value加一
}
for(int i=0; i <= nums.size(); i++) {//从0到n遍历看看缺少哪一个数字
if(numSet[i] == 0) {
return i;
}
}
}
};
第三可以利用高斯公式,计算出理论上应该得到的总数然后减去实际总数,就得到了缺失的数字。
class Solution {
public:
int missingNumber(vector<int>& nums) {
int sum = 0;
int n = nums.size() + 1;//得到理论上应该的总数
for(int i=0; i < nums.size(); i++) {//计算出来此时的总和
sum += nums[i];
}
return ((n*(n-1))/2 - sum);//使用高斯公式计算出来总数减去计算出来的实际数字
}
};
第四可以利用异或,数组的长度n与数组的元素以及下标进行异或,最后如果0到n在数组中存在的部分都会被抵消,只剩下缺失的值。
比如:[0,3,1],数组的长度为3,下标为0、1、2,
进行异或:0^0^3^1^1^2^3=(0^0)^(1^1)^(3^3)^2=2
其实也不难理解,首先数组长度为n,然后下标是0到n-1,这两个就是0到n的完整内容,然后对数组中的元素进行异或,也就是0到n的不完整版本,完整版本与不完整版本进行异或得到的就是差异部分,也就是缺失的值。
class Solution {
public:
int missingNumber(vector<int>& nums) {
int miss = nums.size();
for(int i=0; i<nums.size(); i++) {//进行异或,因为0到n与数组中以及数组长度进行异或的话,相等部分会抵消,最后留下缺失值
miss ^= i ^ nums[i];
}
return miss;
}
};