leetcode 41.缺失的第一个正数

思路:首先就是O(n)时间复杂度,O(n)空间复杂度的,其实很简单,我们只需要定义一个哈希表,遍历一遍数组的时候计数数组中的元素就行;之后再次遍历一遍,只不过这回是从1开始比照哈希表里存不存在这个正整数,从而获得答案。

复制代码
class Solution {
    public int firstMissingPositive(int[] nums) {
        Map<Integer,Integer>map=new HashMap<Integer,Integer>();
        for(int i=0;i<nums.length;i++){
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        }
        int res=0;
        for(int i=1;;i++){
            if(!map.containsKey(i)){
                res=i;
                break;                
            }
        }
        return res;
    }
}

但是,这不是题目本身的初衷。那么我们怎么想到用O(1)的空间复杂度来实现呢?这里我们需要明确一点,那就是我们需要找的正整数一定会在[1,N+1]的范围之内。为什么呢?

我们可以这样想:如果[1,N]的数全在这个数组当中,那么最小的正整数就应该是N+1;

那么如果这个数组中的数全都不是在[1,N]内的数,那么我们就会看到最小正整数就应该是1.那么这个区间就自然而然地推理出来在这个范围之内了。

并没有严格的证明,只是考虑了两种极端的情况,来判断最小正整数的最大值和最小值。

既然答案就在这个区间内,我们怎么判断它是哪一个呢?题解中给出的方法就是如果遍历到数x,那么我们就在坐标x-1的位置标记。如此标记全部完毕之后,如果全部标记完了,那么就说[1,N]的数全在这个数组中;

那么如果没有标记完呢?标记要怎么标记呢?标记就可以让正数变成负数。如果一个数本身就是负数,我们就把这个负数变成>=N+1的数,这样就不影响我们标记数组位置了。这个时候,当我们标记完之后出现正数的坐标+1就是答案了。

复制代码
class Solution {
    public int firstMissingPositive(int[] nums) {
        for(int i=0;i<nums.length;i++){
            if(nums[i]<=0){
                nums[i]=nums.length+2;
            }
        }
        for(int i=0;i<nums.length;i++){
            if(Math.abs(nums[i])>0&&Math.abs(nums[i])<=nums.length){
                if(nums[Math.abs(nums[i])-1]>0)
                nums[Math.abs(nums[i])-1]=-nums[Math.abs(nums[i])-1];
                else
                continue;
            }
        }
        boolean flag=false;
        int res=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0){
                flag=true;
                res=i+1;
                break;
            }
        }
        return flag==true?res:nums.length+1;
    }
}
相关推荐
AI科技星6 分钟前
光速飞行器动力学方程的第一性原理推导、验证与范式革命
数据结构·人工智能·线性代数·算法·机器学习·概率论
橘颂TA8 分钟前
【剑斩OFFER】算法的暴力美学——leetCode 946 题:验证栈序列
c++·算法·leetcode·职场和发展·结构与算法
闻缺陷则喜何志丹10 分钟前
【状态机动态规划】3686. 稳定子序列的数量|1969
c++·算法·动态规划·力扣·状态机动态规划
寻星探路21 分钟前
【算法通关】双指针技巧深度解析:从基础到巅峰(Java 最优解)
java·开发语言·人工智能·python·算法·ai·指针
wen__xvn23 分钟前
力扣第 484 场周赛
算法·leetcode·职场和发展
YuTaoShao34 分钟前
【LeetCode 每日一题】865. 具有所有最深节点的最小子树——(解法一)自顶向下
算法·leetcode·职场和发展
2301_8008951040 分钟前
hh的蓝桥杯每日一题--拔河
职场和发展·蓝桥杯
CCPC不拿奖不改名41 分钟前
计算机网络:电脑访问网站的完整流程详解+面试习题
开发语言·python·学习·计算机网络·面试·职场和发展
寻星探路1 小时前
【算法专题】哈希表:从“两数之和”到“最长连续序列”的深度解析
java·数据结构·人工智能·python·算法·ai·散列表
!停1 小时前
C语言单链表
c语言·数据结构·算法