【Leetcode】448. Find All Numbers Disappeared in an Array

本文介绍LeetCode 448题“查找消失的数组元素”的三种解法:通过标记负数、增加数组长度及交换位置实现O(n)时间复杂度下查找未出现在数组中的数字。

【Leetcode】448. Find All Numbers Disappeared in an Array

@(Leetcode)

链接:https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/

要实现在O(n)时间复杂度和没有额外的空间,就要利用好题目的1 ≤ a[i] ≤ n (n = size of array)这个条件。
参考forum,总的思想有两种:
1. 对缺少的的位置做特殊的标记,这里有两种方法:一个是取负数判别正负,另外一个是加数组长度判别大小是否在数组长度内。
2. 交换位置。

负数标记:

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

加数组长度标记:

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

这里需要注意的地方是:上述代码注释的写法是错误的,刚好为数组长度的那个数会变成-1,造成runtime error。

交换位置:

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        for (int i= 0; i< nums.size(); i++) {
            if (nums[i]!= nums[nums[i]- 1]) {
                swap(nums[i], nums[nums[i]- 1]);
                i--;
            }
        }
        vector<int> ans;
        for (int i= 0; i< nums.size(); i++) {
            if (nums[i]!= i+ 1) {
                ans.push_back(i+ 1);
            }
        }
        return ans;
    }
};

重点是i–,在交换完后,还要对刚换到当前遍历到的位置的数再进行一次交换,不然就会出现有些数字漏交换的情况。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值