响应掘金号召3.6.1 这怎么就简单题?|刷题打卡

196 阅读2分钟

一、题目描述:

二、思路分析:

第一个方法: 类似之前在海量数据讲过的位图法,最后看谁不存在扔数组里返回就完事了

结果发现要求不使用额外空间

那我果断想到了第二个方法,将数组排序,把原有数组当作位图用,这样a[i] != i的返回了就完事了,

结果发现时间复杂度位O(n)

左思右想,查看提示

  1. 如果您决定使用额外的内存,这是一个非常简单的问题。 对于那些试图使用更多内存编写初始解决方案的人,请考虑一下计数器!
  2. 但是,诀窍实际上是不使用超出可用空间的任何额外空间。 有时,多次遍历输入数组有助于找到解决方案。 但是,此问题中有一条有趣的信息,可以轻松地将输入数组本身重新用于解决方案。
  3. 问题指定数组中的数字将在[1,n]范围内,其中n是数组中的元素数。 我们能否使用此信息并以某种方式就地修改数组以找到所需的内容?

看起来时在原有数组上操作的思路是对的,但是时间复杂度的要求实现不了

也就是不使用排序,而使用某种改变数组的值的方法,并保证可以在第二遍循环中确认这里的值是否经历过改变。

三、AC 代码:

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        int n = nums.size();
        for (auto& num : nums) {
            int x = (num - 1) % n;
            nums[x] += n;
        }
        vector<int> ret;
        for (int i = 0; i < n; i++) {
            if (nums[i] <= n) {
                ret.push_back(i + 1);
            }
        }
        return ret;
    }
};

四、总结:

这次简单题离常规的想法有点远,作为数组标签的题,既不是数学题,也不是排序二分动归滑窗,令人困惑,但知道答案之后也会产生原来如此的想法。

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情