携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
一、题目描述:
给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
示例 1:
输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]
示例 2:
输入:nums = [1,1]
输出:[2]
提示:
- n == nums.length
- 1 <= n <= 10^5
- 1 <= nums[i] <= n
进阶:
你能在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。
二、思路分析:
- 用了哈希函数:b[]->a[],但在范围内的存在元素,则b中的相应位置将会=1,证明此元素存在, 然后从 1~N 检查哈希表中没有出现的元素(用一个哈希表 hash 来记录我们在数组中遇到的元素,置1是因为不在意出现的次数)不在原数组操作,开辟了格外空间,但时间复杂度为O(n)
- 不增加额外空间,在原数组操作,那么就要对原数组标记访问过的元素(对a[i]-1数值取反也行),或者由于1<=a[i]<=n,所以我们可以在a[i]-1这个位置统计a[i]出现的次数,同时为了不影响其他数字的统计,只需要加数组长度就行。将数组元素对应为索引的位置加n遍历加n后的数组,若数组元素值小于等于n,则说明数组下标值不存在,即消失的数字
三、AC 代码:
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
int len=nums.size();
vector<int> dp(len);
vector<int> res;
for (int i = 0; i <len;i++)//若在范围内存在此数,则在另外数组对应位置+1即在nums[i]-1记录nums[i]出现
{
dp[nums[i]-1]=1;
}
for(int j=0;j<len;j++)
{
if(dp[j]==0) res.push_back(j+1);//在dp[]中为0,则证明在范围内不存在此数
}
return res;
}
};