当前位置: 首页 > news >正文

力扣HOT100之普通数组:41. 缺失的第一个正数


这道题自己想了一会没想出来,然后就去看题解了,感觉要满足O(n)的时间复杂度,还要满足O(1)的空间复杂度还蛮难的,这里主要把题解的思路讲一下,很巧妙。
对于输入数组nums,我们假设其长度为N,那么结果一定在[1, N + 1]中产生,最极端的情况就是nums中的元素为从1N这N个连续正整数,那么结果就是N + 1,否则其他情况下,结果一定从[1, N]中产生。那么我们知道了这个性质以后,就可以对数组进行进一步的处理,我们将nums[i]放置在下标为nums[i] - 1处,对于nums[i] <= 0nums[i] > nums.size()的情况,我们不作任何处理,因为再怎么处理也没用,此外,若下标为nums[i] - 1处的元素与下标为i处的元素(nums[i])相等,我们也不做处理,因为换了也是白换。我们首先用for循环遍历一遍数组nums,对于下标i处的元素nums[i],我们将其与下标为nums[i] - 1处的元素(nums[nums[i] - 1])进行交换,交换完之后,下标为nums[i] - 1处放置的元素是正确的,但是交换过来的值是否能与下标i匹配上,我们是不知道的,然而我们在前面提到,每进行一次for循环,在数组内存在对应的正确元素时(不存在的话就无能为力了),我们一定能保证下标为i处的元素为i + 1,因此这个交换应当是一个持续的过程,我们应该用一个while循环来实现。当经历过N次for循环后,我们可以保证:对于能正确放置在下标为i处的元素,其值一定为i + 1,因此我们只需要从左往右再遍历一次数组,检查数组的元素是否与其下标对应,如果发现某个位置上的元素nums[i] != i + 1,就说明数组缺少i + 1这个正整数,直接返回i + 1即可,如果整个for循环都没有出现这样的情况,就说明遇到了最极端的情况:nums中的元素为[1, N]这连续N个正整数,我们直接返回N + 1即可。代码注释也写的很详细,可以看看。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        //将nums[i]放置在nums[nums[i] - 1]的位置上
        for(int i = 0; i < nums.size(); ++i){
            //外层for循环每循环一次,在数组中存在i + 1这个元素的情况下,一定能确保
            //i + 1被交换到nums[i]处,如果不存在的话就不动它
            while(nums[i] != i + 1){  //数值与下标不匹配的情况
                if(nums[i] <= 0 || nums[i] > nums.size() || nums[i] == nums[nums[i] - 1])
                    //第一个和第二个判断条件是指nums[i] - 1超出数组的下标范围,无法被放置在数组内的任何位置
                    //第三个判断条件是指nums[i]即将与nums[nums[i] - 1]处的数值交换,但是发现两个位置的
                    //数值大小一样,这就没必要交换了,否则会陷入无限循环中
                    break;
                int index = nums[i] - 1;  //当前遍历到的nums[i]应当放置到下标为index的位置
                nums[i] = nums[index];   //先将下标为index处的元素转移过来,防止被覆盖
                nums[index] = index + 1;
                //对于被交换过来的nums[index](现在的nums[i],我们不能保证nums[i] == i + 1,因此要继续寻循环)
            }
        }
        for(int i = 0; i < nums.size(); ++i){
            if(nums[i] != i + 1)
                return i + 1;
        }
        return nums.size() + 1;
    }
};
http://www.dtcms.com/a/99787.html

相关文章:

  • Cannot find a valid baseurl for repo: centos-sclo-sclo/x86_64
  • Vue实现的表格多选方案支持跨页选择和回显功能
  • DNS网络攻击:原理剖析、危害解读与全面防御指南
  • 【Python LeetCode 专题】每日一题
  • 【20期获取股票数据API接口】如何用Python、Java等五种主流语言实例演示获取股票行情api接口之沪深A股实时最新分时MACD数据及接口API说明文档
  • 本地缓存之Guava Cache
  • Linux CentOS 7 搭建我的世界服务器详细教程 (丐版 使用虚拟机搭建)
  • CTFshow命令执行(55-71)
  • 24_原型和原型链_this
  • GitHub上免费学习工具的精选汇总
  • 数字电路基础
  • 【Java/数据结构】优先级队列(PriorityQueue)(图文版)
  • PDF处理控件Aspose.PDF教程:通过C#、Java 和 Python删除 PDF中的水印
  • 测试cursor-AI编辑器
  • Python FastApi(8):模式的额外信息、额外数据类型
  • java网盘项目,文件和文件夹用两个表还是一个表,两个表理论查询效率慢了为啥要用,有啥优势
  • 数据结构 KMP 字符串匹配算法
  • 《Python Web部署应知应会》No2:如何基于FastAPI 和 OLLAMA 架构实现高并发 AI 推理服务
  • leetcode刷题日记——跳跃游戏 II
  • 编程语言
  • 【每日论文】DINeMo: Learning Neural Mesh Models with no 3D Annotations
  • Visual Studio中创建和配置设置文件(Settings.settings) - 详细步骤指南——待调试
  • 基于springboot小说题材在线阅读平台(源码+lw+部署文档+讲解),源码可白嫖!
  • QLoRA对大模型微调
  • Ubuntu 22 Linux上部署DeepSeek R1保姆式操作详解(ollama方式)
  • 基于Elasticsearch的个性化内容推荐技术实践
  • 方案推介:80页产品经理培训PPT课件:产品调研、用户画像、用户需求的收集【文末附下载链接】
  • vue3+bpmn.js基本使用
  • 缓存击穿中的二次判断
  • 鸿蒙项目源码-仿抖音短视频-原创!原创!原创!