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

《LeetCode热题100》---<5.③普通数组篇五道>

本篇博客讲解LeetCode热题100道普通数组篇中的五道题

第五道:缺失的第一个正数(困难)

第五道:缺失的第一个正数(困难)

方法一:将数组视为哈希表 

class Solution {public int firstMissingPositive(int[] nums) {int n = nums.length;for (int i = 0; i < n; ++i) {if (nums[i] <= 0) {nums[i] = n + 1;}}for (int i = 0; i < n; ++i) {int num = Math.abs(nums[i]);if (num <= n) {nums[num - 1] = -Math.abs(nums[num - 1]);}}for (int i = 0; i < n; ++i) {if (nums[i] > 0) {return i + 1;}}return n + 1;}
}

1.将负数,0,替换为n+1变成无效数字,因为我们只关心[1,n]的正数。

2.标记已存在的正整数,对于每一个元素 `nums[i]`,我们用它的绝对值 `num` 来表示。如果num是一个有效的数字,也就是num<=n。那么将数组中索引num-1的元素下标记为负数。这一步结束后,数组中所有出现过的正整数对应的索引位置都会被标记为负数。

3.查找第一个未被标记的位置。查找第一个仍然为正数的元素。此时返回i+1。

4.如果没有找到返回n+1

复杂度分析

  • 时间复杂度:O(N),其中 N 是数组的长度。

  • 空间复杂度:O(1)。

 

方法二:置换(恢复)

class Solution {public int firstMissingPositive(int[] nums) {int n = nums.length;for (int i = 0; i < n; ++i) {while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {int temp = nums[nums[i] - 1];nums[nums[i] - 1] = nums[i];nums[i] = temp;}}for (int i = 0; i < n; ++i) {if (nums[i] != i + 1) {return i + 1;}}return n + 1;}
}

除了打标记以外,我们还可以使用置换的方法,将给定的数组「恢复」成下面的形式: 

  • 遍历数组:对于每个元素,将其放置在正确的位置上,即把数字 nums[i] 放在索引 nums[i] - 1 的位置上。通过不断交换,确保每个正整数 k 出现在索引 k-1 的位置上。
  • 检查数组:再遍历一次数组,找到第一个位置 i 使得 nums[i] != i + 1,即第一个缺失的正整数是 i + 1
  • 返回结果:如果所有位置都满足 nums[i] == i + 1,则返回 n + 1,即数组长度加一的值。

复杂度分析

  • 时间复杂度:O(N),其中 N 是数组的长度。

  • 空间复杂度:O(1)。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • cf935:D.Seraphim the Owl(贪心)
  • c++入门基础(下篇)————引用、inline、nullptr
  • 爬虫:xpath模块及昵图网实例
  • 宏编程:C++宏、Rust宏和Lisp宏比较
  • [GWCTF 2019]我有一个数据库1
  • 24年电赛——自动行驶小车(H题)MSPM0G3507-编码电机驱动与通用PID
  • unity 小怪播放动画导致ui抖动
  • C-V2X通信协议
  • 正点原子imx6ull-mini-Linux驱动之Linux LCD 驱动实验(19)
  • 【数据泄露】最新 FBI 官员数据库泄露事件
  • createObjectURL的部分使用讲解
  • 锅总浅析防火墙
  • 三线程分别打印1、2、3顺序执行10次
  • 游戏加速器推荐 网游加速器排行榜
  • 快速将网站从HTTP升级为HTTPS
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • android 一些 utils
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • Git 使用集
  • Javascript 原型链
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • JAVA之继承和多态
  • Leetcode 27 Remove Element
  • Python中eval与exec的使用及区别
  • 百度地图API标注+时间轴组件
  • 二维平面内的碰撞检测【一】
  • - 概述 - 《设计模式(极简c++版)》
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 近期前端发展计划
  • 前端存储 - localStorage
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 使用API自动生成工具优化前端工作流
  • 微服务框架lagom
  • 写给高年级小学生看的《Bash 指南》
  • 学习笔记TF060:图像语音结合,看图说话
  • 原生 js 实现移动端 Touch 滑动反弹
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​queue --- 一个同步的队列类​
  • # 数论-逆元
  • #C++ 智能指针 std::unique_ptr 、std::shared_ptr 和 std::weak_ptr
  • #Linux(make工具和makefile文件以及makefile语法)
  • #Linux(帮助手册)
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (2.2w字)前端单元测试之Jest详解篇
  • (SpringBoot)第七章:SpringBoot日志文件
  • (转)linux下的时间函数使用
  • (转)四层和七层负载均衡的区别
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • (转载)Linux 多线程条件变量同步
  • .Net IOC框架入门之一 Unity
  • .NET 给NuGet包添加Readme
  • .NET6实现破解Modbus poll点表配置文件