day56 448.找到所有数组中消失的数字()

82 阅读3分钟

题目来源: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 数组,其中包含缺失的数字。
  • 加强理解:因为 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 天,点击查看活动详情