题目来源:448.找到所有数组中消失的数字
题目描述:
- 描述: 给你一个含 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]
思路
- 我们需要使用到数组这种数据结构,将所有重复出现的位置进行标记的操作,然后通过对数组的二次遍历,这样就可以顺利的找到没有在数组中出现过的数字
操作:- 第一个 for 循环遍历
nums数组,对于每个数字num,它使用公式abs(num) - 1计算它在数组中的位置pos。由于输入向量可能包含负数,因此使用绝对值来获取正确的位置 - 如果在
nums数组的pos位置上的数字为正数,则通过将其设置为其负值来将其标记为负数。这一步确保nums数组中的每个位置只标记一次。 - 第二个 for 循环遍历
nums数组,并检查正数的位置。如果i位置上的数字为正数,则表示数字i+1在输入向量中缺失。因此,将i+1添加到ans数组中。 - 最后,返回
ans数组,其中包含缺失的数字。
- 第一个 for 循环遍历
加强理解:因为 1.n 个整数的数组 nums;2.数组nums[i]在区间 [1, n] 内- 从上面这两个已知条件可以得知,如果nums数组没有发生缺失的话,nums[i]-1在区间[0,n-1],这样的话,将nums[i]-1作为数组nums的下标,那么将所有的nums[nums[i]-1]遍历一遍的话,得到的就是完整的nums数组
- 反之,如果将nums[i]-1作为数组nums的下标,将所有的nums[nums[i]-1]遍历一遍,然后将每个遍历到的nums数组的元素被标记为负数,那么最终剩下的整数就是没有被遍历到的,所以这些正数所在的数组下标i进行+1的操作后,得到就是缺失的数字
具体实现:
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) { //实现方法
vector<int> ans;
for (const int & num: nums) {
int pos = abs(num) - 1;
if (nums[pos] > 0) {
nums[pos] = -nums[pos];
}
}
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] > 0) {
ans.push_back(i + 1);
}
}
return ans;
}
};
int main() { //测试
/*
* 要在main函数中调用这个Solution类的方法findDisappearedNumbers,你需要先创建
* 一个Solution类的对象,并将需要进行查找缺失数字的整数数组作为参数传递给该方法。
* 然后,将返回的结果存储在另一个 `vector` 对象中
*/
vector<int> nums = {4,3,2,7,8,2,3,1}; //初始化一个整数数组nums
Solution solution;
//将nums作为参数传递给`Solution` 类的 `findDisappearedNumbers` 方法
//并将返回的结果存储在 `missingNumbers` 中
vector<int> missingNumbers = solution.findDisappearedNumbers(nums);
for (int i = 0; i < missingNumbers.size(); i++) { //遍历missingNumbers,打印出缺失的数字
cout << missingNumbers[i] << " ";
}
cout << endl;
return 0;
}
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 30 天,点击查看活动详情”