题目: 448. 找到所有数组中消失的数字 - 力扣(LeetCode) (leetcode-cn.com)
思路一:排序
分析: 找到所有在 [1, n] 范围之间没有出现在数组中的数字,将数组进行排序,然后查找前后的数相差是否为0或者1,如果不满足,则存在没有出现过的数字。尤其注意开头和最后一个元素,首元素是否为1,最后一个元素是否等于长度
步骤:
-
将数组进行排序
-
判断首元素是不是1,不为1,就将【1,nums[0]】之间的数存入数组
-
遍历数组,判断前后元素是不是相差0或1,不是,就将两个元素之间的值存入数组
-
判断数组最后一位是不是len,不是,就将【nums[len-1],len】之间的数存入数组
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int len=nums.size();
if(len==0)
return result;
sort(nums.begin(),nums.end());
if(nums[0]!=1)
{
if(len==1)
return{1};
else
{
int count=nums[0]-1;
for(int i=0;i<count;i++)
{
result.push_back(1+i);
}
}
}
for(int i=1;i<len;i++)
{
if(nums[i]-nums[i-1]==0||nums[i]-nums[i-1]==1)
continue;
else
{
int count=nums[i]-nums[i-1];
for(int j=1;j<count;j++)
{
result.push_back(nums[i-1]+j);
}
}
}
if(nums[len-1]!=len)
{
int count=len-nums[len-1];
for(int i=1;i<=count;i++)
{
result.push_back(nums[len-1]+i);
}
}
return result; }
思路二:哈希表法
分析:
将数组元素存入哈希表,然后查找【1,n】的数在哈希表中出现过吗,没有则存入数组。
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int len=nums.size();
unordered_map<int,int>map;
sort(nums.begin(),nums.end());
for(int num:nums)
{
map[num]++;
}
for(int i=1;i<=len;i++)
{
if(map.find(i)==map.end())
result.push_back(i);
}
return result;
}
选用set, 因为怒用关注数组元素出现的次数
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int len=nums.size();
set<int>map;
sort(nums.begin(),nums.end());
for(int num:nums)
{
map.insert(num);
}
for(int i=1;i<=len;i++)
{
if(map.find(i)==map.end())
result.push_back(i);
}
return result;
}
思路三:原地修改
步骤:
- 遍历数组的每个元素
- 我们将把 |nums[i]|-1 索引位置的元素标记为负数。即 nums[[∣nums[i]∣−1]×−1 。
- 然后遍历数组,若当前元素nums[i]为负数,说明数组存在数字i+1
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int len=nums.size();
for(int i=0;i<len;i++)
{
if(nums[abs(nums[i])-1]<0)
continue;
else
{
nums[abs(nums[i])-1]*=-1;
}
}
for(int i=0;i<len;i++)
{
if(nums[i]>0)
result.push_back(i+1);
}
return result;
}
思路四:原地修改
步骤:
- 将数组元素对应为索引的位置加n
- 遍历加n后的数组,若数组元素值小于等于n,则说明数组下标值不存在,即消失的数字
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> res;
if(nums.empty()) return nums;
for(int i=0;i<nums.size();i++)
{
int index=(nums[i]-1)%nums.size();
nums[index]+=nums.size();
}
for(int i=0;i<nums.size();i++)
{
if(nums[i]<=nums.size())
res.push_back(i+1);
}
return res;
}
};
思路五:类似桶排序
分析:
将0加入数组,数组里面的元素都在【1,n】范围,将元素放到对应下标的位置即i=nums[i],没出现的元素,对应下标的位置上一定不和下标相等,加入结果元素即可
步骤:
-
将0加入数组
-
遍历数组
-
如果nums[i]!=nums[nums[i]](以该元素为数组下标的位置上的值不和下该元素相等即元素下标不等于元素,就交换)
-
遍历数组,如果数组下标和对应的数组元素不相等,就将元素加入结果数组
-
返回结果数组
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
//因为下标从0开始,所以先把0插到尾部
nums.push_back(0);
//遍历数组如果该下标位置和该元素为下标时值不相等则交换位置
for(int i=0;i<nums.size();i++){
while(nums[i]!=nums[nums[i]])
swap(nums[i],nums[nums[i]]);
}
//在遍历一次数组这一次用相对位置去比较,如果相对位置不一样则该位置就是消失的数
vector<int> ans;
for(int i=1;i<nums.size();i++){
if(i!=nums[i])
ans.push_back(i);
}
return ans;
}
};