原题地址(简单)

方法1—原地修改

思路

这道题,没想出来怎么在不使用额外空间且时间复杂度为448. 找到所有数组中消失的数字 - 图1的情况下做出来,后来看了官方题解。
其实题解的本质是什么呢?
就是利用nums数组下标为0~n-1,来标记出nums数组中出现的数,进而就能筛选出没出现的数。
比如官方题解中的+n操作,其实也可以取负,具体来说就是遍历nums,将448. 找到所有数组中消失的数字 - 图2取负,再遍历1~n,不是负数的,就说明它未出现。

代码

+n操作

  1. class Solution {
  2. public:
  3. vector<int> findDisappearedNumbers(vector<int>& nums) {
  4. int i, n = nums.size();
  5. for(auto num : nums) {
  6. i = (num - 1) % n;
  7. nums[i] += n;
  8. }
  9. vector<int> v;
  10. for(int j=0; j<n; j++){
  11. if(nums[j] <= n) v.emplace_back(j+1);
  12. }
  13. return v;
  14. }
  15. };

取负操作

  1. class Solution {
  2. public:
  3. vector<int> findDisappearedNumbers(vector<int>& nums) {
  4. int n = nums.size();
  5. for(int i=0; i<n; i++) {
  6. int idx = abs(nums[i])-1;
  7. if(nums[idx] > 0)
  8. nums[idx] *= -1;
  9. }
  10. vector<int> v;
  11. for(int j=0; j<n; j++){
  12. if(nums[j] > 0) v.emplace_back(j+1);
  13. }
  14. return v;
  15. }
  16. };

时空复杂度

448. 找到所有数组中消失的数字 - 图3