• LeetCode 448 Find All Numbers Disappeared in an Array


    Problem:

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

    Find all the elements of [1, n] inclusive that do not appear in this array.

    Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

    Example:

    Input:
    [4,3,2,7,8,2,3,1]
    
    Output:
    [5,6]

    Summary:

    长度为n的整形数组a中的所有数大于等于1,小于等于n,其中可能包含重复两次的数字。

    输出[1, n]中不存在于数组a中的数字集合。

    Solution:

    1. 首先想到的方法是用map创建Hash表,key为数组中出现的数字,value为出现次数,再寻找哪个数字出现0次。

     1 class Solution {
     2 public:
     3     vector<int> findDisappearedNumbers(vector<int>& nums) {
     4         int len = nums.size(), maxNum = -1;
     5         sort(nums.begin(), nums.end());
     6         map<int, int> m;
     7         vector<int> res;
     8         
     9         for (int i = 0; i < len; i++) {
    10             m[nums[i]]++;
    11             maxNum = maxNum < nums[i] ? nums[i] : maxNum;
    12         }
    13         
    14         for (int i = 1; i <= len; i++) {
    15             if (!m[i]) {
    16                 res.push_back(i);
    17             }
    18         }
    19         
    20         return res;
    21     }
    22 };

    但题目中要求不开数组标记,故这个方法不可行。

    2. 不消耗其余空间的做法,首先想到的是将数组排序,用一个变量k记录下一个需要查找的[1, n]中的数字,将不存在于数组中的数字存下来。

    需要注意的出现重复数字时的处理。

     1 class Solution {
     2 public:
     3     vector<int> findDisappearedNumbers(vector<int>& nums) {
     4         int len = nums.size();
     5         sort(nums.begin(), nums.end());
     6         vector<int> res;
     7         
     8         int k = 1;
     9         for (int i = 0; i < len; i++) {
    10             if (k != nums[i]) {
    11                 while (k < nums[i]) {
    12                     res.push_back(k++);
    13                 }
    14             }
    15             
    16             if (i < len - 1 && nums[i] == nums[i + 1]) {
    17                 i++;
    18             }
    19             
    20             k++;
    21         }
    22         
    23         while (k <= len) {
    24             res.push_back(k++);
    25         }
    26         
    27         return res;
    28     }
    29 };

    但因为有排序,时间复杂度为O(nlogn),不满足题目中的O(n),故这种方法仍不可行。

    3. 由于题目中有数组中所有数字都大于等于1且小于等于n,而n为数组长度这一条件。所以可以以数组下标作为索引标记哪些数字出现过,标记方法为将出现数字对应下标的数字标为负数。

    1. 计算出数组中出现的数字x的下标形式,则下表为index = |x| - 1,可将数组a中得a[index]标为负数来标记数字x出现在数组中
    2. 若数组中某数字已为负数,说明该数字在数组中出现过
    3. 最终遍历数组,若a[i]为正数,表明数字 i + 1在数组中没有出现过。

    这种方法仅遍历两次数组即可完成,切不用消耗其余空间。

     1 class Solution {
     2 public:
     3     vector<int> findDisappearedNumbers(vector<int>& nums) {
     4         int len = nums.size();
     5         vector<int> res;
     6         for (int i = 0; i < len; i++) {
     7             int index = abs(nums[i]) - 1;
     8             if (nums[index] > 0) {
     9                 nums[index] *= -1;
    10             }
    11         }
    12         
    13         for (int i = 0; i < len; i++) {
    14             if (nums[i] > 0) {
    15                 res.push_back(i + 1);
    16             }
    17         }
    18         
    19         return res;
    20     }
    21 };
  • 相关阅读:
    学习进度笔记1——安装scala
    随堂测试——数据清洗
    Mapreduce实例——Webcount
    第十七周个人总结
    ppt转为.scr(屏保)
    navicat15 破解
    vue echarts饼图封装以及同一个组件2个饼图不加载问题解决
    阿里云 django+vue前后端分离汇总
    阿里云 django+vue前后端分离 前端打包上传
    阿里云服务器 django+vue前后端分离 nginx配置
  • 原文地址:https://www.cnblogs.com/VickyWang/p/6232635.html
Copyright © 2020-2023  润新知