LeetCode 41. 缺失的第一个正数(C++)*

思路:
1.每遍历一个元素就比较在1-n之间是否有元素缺失,暴力遍历;时间复杂度会很高
2.使用哈希表来记录每个元素的出现次数,需要用到额外的空间
3.使用原数组来代替哈希表的功能,首先知道对于长度为n的数组,要么就是1-n的元素全出现,对应位置为[0,n-1],那么答案为n+1,要么就在1-n中的元素缺失;首先对于小于0的元素变为n+1,再遍历一遍,将所有元素-1的绝对值对应的位置的元素变为负数(比如说我元素为2,那就把坐标1的元素变为负数),这样最后剩下的元素为正的位置处的元素要么就是n+1,要么该位置就是缺失的元素-1。
4.通过置换的方法,把每个出现在的1-n的元素放到对应的元素-1的位置上,那么最后遍历一次元素和他位置+1不匹配的那么位置+1就是缺失的元素。
原题链接:https://leetcode.cn/problems/first-missing-positive/?favorite=2ckc81c

1.题目如下:

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1:

输入:nums = [1,2,0]
输出:3

示例 2:

输入:nums = [3,4,-1,1]
输出:2

示例 3:

输入:nums = [7,8,9,11,12]
输出:1

提示:

1 <= nums.length <= 5 * 105
-231 <= nums[i] <= 231 - 1

2.代码如下:

class Solution {
public:
//思路一:用哈希表,但是空间复杂度为O(n)

//思路二:暴力搜索,从1到n依次检索数组中是否有该数字 时间复杂度O(n2)

//思路三:使用置换方法;
/*
    对于所有元素,在1-n应该都有一个对应的位置,如果位置不是对应的,就交换元素;
    最后遍历的时候,如果坐标位置上的元素不等于该坐标+1,就是该元素缺失
*/
    int firstMissingPositive(vector<int>& nums) {
        int n=nums.size();
        for (int i=0;i<n;++i) {
            //如果元素在1-n区间,那么就一定会有一个对应的位置,如果不在该位置,就交换
            while (nums[i]>0 && nums[i]<=n && nums[nums[i]-1]!=nums[i]) {
                swap(nums[nums[i]-1],nums[i]);
            }
        }
        for (int i=0;i<n;++i) {
            if (nums[i]!=i+1) {
                return i+1;
            }
        }
        return n+1;
    }

//思路四:创建哈希表的替代品 可知,没有出现的数字只有可能在1到n+1中;
/*
    遍历数组,同时对小于0的数设为n+1
    对于大于0小于n的数,将元素对应的位置的元素设为负数
*/
/*
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for (int& num: nums) {
            if (num <= 0) {
                num = n + 1;
            }
        }
        for (int i = 0; i < n; ++i) {
            int num = abs(nums[i]);
            if (num <= n) {
                // ∣x∣−1 位置的数添加一个负号
                nums[num - 1] = -abs(nums[num - 1]);
            }
        }
        for (int i = 0; i < n; ++i) {
            //如果一个位置元素大于0,则返回i+1
            if (nums[i] > 0) {
                return i + 1;
            }
        }
        return n + 1;
    }
    */
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_panbk_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值