首页 > 其他分享 >41. 缺失的第一个正数

41. 缺失的第一个正数

时间:2024-01-22 22:57:37浏览次数:19  
标签:遍历 标记 nums 41 索引 num 数组 正数 缺失

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

2.题解

2.1 哈希表+标记法

思路

实际上,对于一个长度为 NNN 的数组,其中没有出现的最小正整数只能在 [1,N+1][1, N+1][1,N+1] 中。这是因为如果 [1,N][1, N][1,N] 都出现了,那么答案是 N+1,否则答案是 [1,N] 中没有出现的最小正整数。这样一来,我们将所有在 [1,N] 范围内的数放入哈希表,也可以得到最终的答案。而给定的数组恰好长度为 N,这让我们有了一种将数组设计成哈希表的思路:

我们对数组进行遍历,对于遍历到的数 x,如果它在 [1,N] 的范围内,那么就将数组中的第 x−1 个位置(注意:数组下标从 0 开始)打上「标记」。在遍历结束之后,如果所有的位置都被打上了标记,那么答案是 N+1,否则答案是最小的没有打上标记的位置加 1。

那么如何设计这个「标记」呢?由于数组中的数没有任何限制,因此这并不是一件容易的事情。但我们可以继续利用上面的提到的性质:由于我们只在意 [1,N] 中的数,因此我们可以先对数组进行遍历,把不在 [1,N] 范围内的数修改成任意一个大于 N 的数(例如 N+1)。这样一来,数组中的所有数就都是正数了,因此我们就可以将「标记」表示为「负号」。算法的流程如下:

我们将数组中所有小于等于 0 的数修改为 N+1;

我们遍历数组中的每一个数 x,它可能已经被打了标记,因此原本对应的数为 ∣x∣。如果 ∣x∣∈[1,N],那么我们给数组中的第 ∣x∣−1个位置的数添加一个负号。注意如果它已经有负号,不需要重复添加;

在遍历完成之后,如果数组中的每一个数都是负数,那么答案是 N+1,否则答案是第一个正数的位置加 1。

代码

1.这里为何要标记 nums[num - 1] 为负号,而不是直接标记 nums[i] 为负号呢?
这里有一个最终寻找的问题,如果我们直接标记 nums[i],那么最后我是按索引顺序遍历数组的,标记散落在各处,有可能是遇到的第一个非标记处是最小的,也可能是最后一个或者其中的任意一个非标记处。 比如像 3, -1, 2, 4 => -3, 5(4+1), -2, -4, 根本找不到究竟哪一个是缺失的第一个正数.

而nums[num - 1] 实际上是直接上将要标记的数化为有序的索引进行标记,这样我按索引顺序遍历到的第一个标记,就是最小的num - 1
而按照这种标记方式, 3, -1, 2, 4 => 3, -5(2-1 = 1), -2(3-1 = 2), -4(4-1=3), 找到的第一个非标记处便是索引0的位置,返回0+1 = 1即可
像是1,-1,2,3 => -1(1-1=0), -5(2-1=1), -2(3-1=2), 3, 第一个非标记处索引为3,即返回3+1 = 4即可
这里标记和索引的单调性共同完成了任务。

2.为何使用的是num-1 而不是num? 因为[1,N]这几个数对应数组索引的[0,N-1]

3.这里为何不直接在一个循环内处理[-∞,0],[N+1,+∞] 和 [1,N] 中的内容?
就像: for(int i = 0; i < N; i++){
if(nums[i] > N || nums[i] <= 0) nums[i] = N+1;
else{nums[nums[i] - 1] = -abs(nums[nums[i] - 1]);}
}
首先这样的话判断条件中nums[i]<=0就可能不是这个数本来是负数,而是被标记后成为了负数,后续我遍历到这个数的时候,就会错误地被化为N+1
其次由于这里nums[i]的值可能为负数,所以我们在第二个循环中使用abs取绝对值进行比较

4.寻找第一个非标记处,其索引+1即所求位置。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int N = nums.size();
        for(int i = 0; i < N; i++){ // for(int &num: nums) 这种形式加个&也可以改变数组中的值
            if(nums[i] > N || nums[i] <= 0) nums[i] = N+1;
        }
        for(int i = 0; i < N; i++){
            int num = abs(nums[i]);
            if(num <= N) 
                nums[num - 1] = -abs(nums[num - 1]);
        }
        for(int i = 0; i < N; i++)
            if(nums[i] > 0) return i + 1;
        return N + 1; 
    }
};

标签:遍历,标记,nums,41,索引,num,数组,正数,缺失
From: https://www.cnblogs.com/trmbh12/p/17981307

相关文章

  • 4147:汉诺塔问题(Tower of Hanoi)C++
    递归C和C++一样,就写个C++了。#include<iostream>usingnamespacestd;voidmove(intn,chara,charb,charc){if(n<=0)return;move(n-1,a,c,b);cout<<n<<":"<<a<<"->"<<c<<'\n�......
  • Go语言核心36讲 41 | io包中的接口和工具 (下)
    上一篇文章中,我主要讲到了io.Reader的扩展接口和实现类型。当然,io代码包中的核心接口不止io.Reader一个。我们基于它引出的一条主线,只是io包类型体系中的一部分。我们很有必要再从另一个角度去探索一下,以求对io包有更加全面的了解。下面的一个问题就与此有关。知识扩展问题:i......
  • P4148 简单题 题解
    QuestionP4148简单题有一个\(n\timesn\)的棋盘,每个格子内有一个整数,初始时全部为\(0\),现在需要维护两种操作1xy将格子\(x,y\)里的数字加上\(A\)2x1y1x2y2输出\(x_1,y_1,x_2,y_2\)这个矩形内的数字和强制在线Solution因为强制在线,没法用CDQ什么乱搞,这......
  • 可扩展、CY8C4148AZAS595、CY8C4148AZAS568、CY8C4148AZAS558支持更低的成本HMI应用,BT
    一、PSoC™Automotive4100SMaxMCU 1、说明PSoC4100SMax采用CAPSENSE技术,拥有7x7mm²、10x10mm²和14x14mm²三种封装尺寸,支持工业控制、汽车人机交互(HMI)、智能家居自动化及大型家用电器,如机器人、电感式传感器、洗衣机、冰箱、空调、智能温控器、打印机等。P......
  • 题解 CF741E Arpa’s abnormal DNA and Mehrdad’s deep interest
    CF741EArpa’sabnormalDNAandMehrdad’sdeepinterest记\(R_{i}\)表示把\(T\)插入在\(S\)的第\(i\)位后组成的字符串。有\(q\)组询问,给定\((x,y,l,r)\),求\(\min_{i}R_{i},({i\in[l,r],i\%k\in[x,y]})\)。一个暴力的想法是先把\(R_{i}\)的排名求出来,这显......
  • 恩比德41+7+10约基奇空砍25+19 76人力克掘金
    恩比德41+7+10约基奇空砍25+1976人力克掘金北京时间1月17日,NBA常规赛,76人126-121力克掘金。  76人(26-13):恩比德41分7篮板10助攻、马克西25分5篮板9助攻、哈里斯24分5篮板4助攻、乌布雷11分5篮板、巴图姆8分4篮板2助攻2帽、贝弗利8分2篮板2助攻掘金(28-13):约基奇25分......
  • 41. 干货系列从零用Rust编写负载均衡及代理,websocket与tcp的映射,WS与TCP互转
    wmproxywmproxy已用Rust实现http/https代理,socks5代理,反向代理,静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代理等,会将实现过程分享出来,感兴趣的可以一起造个轮子项目地址国内:https://gitee.com/tickbh/wmproxygithub:https://github.com/......
  • 4412 设备树 qt busybox , ctrl+c 无法终止 程序
    问题: 在系统中,ctrl+c无法终止程序。背景: 软件:迅为网盘设备树镜像。硬件:迅为4412板卡。  网上的截图:   我自己的改动如下;     结果显示: ......
  • CF414B - Mashmokh and ACM
    思路dp。dp[i][j]表示第i位填j时的方案数ac代码#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;consti64inf=8e18;typedefpair<int,int>pii;constintmod=1e9+7;constintN=2e3+5;intdp[N][N];vector<int>g[N];voi......
  • ORA-01041: internal error: hostdef extension doesn't exist错误侦察
    如果在使用netca工具安装监听时就发生了ORA-01041:internalerror:hostdefextensiondoesn'texist的错误,可能是由于配置或环境设置的问题。以下是一些建议的步骤:检查环境变量:确保ORACLE_HOME和ORACLE_SID等必要的环境变量已经正确设置。在使用netca工具时,确保使用了......