每日一题:缺失的第一个正数

2024-04-14 19:12
文章标签 每日 第一个 缺失 正数

本文主要是介绍每日一题:缺失的第一个正数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

示例 1:

输入:nums = [1,2,0]
输出:3
解释:范围 [1,2] 中的数字都在数组中。

示例 2:

输入:nums = [3,4,-1,1]
输出:2
解释:1 在数组中,但 2 没有。

示例 3:

输入:nums = [7,8,9,11,12]
输出:1
解释:最小的正数 1 没有出现。

提示:

  • 1 <= nums.length <= 105
  • -2^31 <= nums[i] <= 2^31 - 1

如果没有时间、空间复杂度要求,那么可以使用哈希表存储数组中出现的每一个元素,然后从正整数1开始枚举,直到找到不在表内的正整数即为所求。

但由于限制了时间复杂度O(n),使用常数级别的额外空间。也就是要求每个元素只遍历一次,且不能创建长度为n的数据结构。

所以使用考虑使用原地哈希。将哈希表存储在要哈希的数组中。

对于一个长度为 N 的数组,其没有出现的最小正整数只能在 [1,N+1] 中。

因此我们想要构建的目标数组形式如下:

  • 以[3,-1,4,1]为例。需要通过变换,让它变成[1,-1,3,4]的形式。
  • 考虑下标,nums[i]存储的值,就是i+1。而转换后第一个不满足这个条件的位置,就是缺少的第一个正整数。

第一步:i = 0,nums[i] = 3 != i+1,因此需要将nums[i]的值与nums[nums[i] - 1]交换。

第二步,i 仍然为0,因为当前位置没有被交换为1。继续交换。

此时,i = 0位置上的数已经符合要求了,i++。

这里如果起始数组里没有1这个数字,也就是说缺失的就是1会发生什么?

--- 在经过多次循环交换后,要么这个位置的值小于0,要么大于n+1,要么像后文所述,出现了重复数字。

所以要注意循环跳出条件。

这个例子中,到这一步其实就已经完成交换了,接下来就是遍历完所有的i,结束。

代码:

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

额外关注下nums[nums[i] - 1] != nums[i]这个循环跳出条件。

由于题目不保证一个数只出现一次,如果交换的两个数恰好相等,那么就会陷入死循环,所以加入这个条件跳出循环。

这篇关于每日一题:缺失的第一个正数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/903778

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

Spring Roo 实站( 一 )部署安装 第一个示例程序

转自:http://blog.csdn.net/jun55xiu/article/details/9380213 一:安装 注:可以参与官网spring-roo: static.springsource.org/spring-roo/reference/html/intro.html#intro-exploring-sampleROO_OPTS http://stati

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

使用gradle做第一个java项目

涉及到的任务如下: assemble任务会编译程序中的源代码,并打包生成Jar文件,这个任务不执行单元测试。 Total time: 5.581 secs E:\workspace\Test>gradle assemble :compileJava :processResources UP-TO-DATE :classes :findMainClass :jar :b

vue2实践:第一个非正规的自定义组件-动态表单对话框

前言 vue一个很重要的概念就是组件,作为一个没有经历过前几代前端开发的我来说,不太能理解它所带来的“进步”,但是,将它与后端c++、java类比,我感觉,组件就像是这些语言中的类和对象的概念,通过封装好的组件(类),可以通过挂载的方式,非常方便的调用其提供的功能,而不必重新写一遍实现逻辑。 我们常用的element UI就是由饿了么所提供的组件库,但是在项目开发中,我们可能还需要额外地定义一

力扣 739. 每日温度【经典单调栈题目】

1. 题目 理解题意: 1.1. 给一个温度集合, 要返回一个对应长度的结果集合, 这个结果集合里面的元素 i 是 当前 i 位置的元素的下一个更高温度的元素的位置和当前 i 位置的距离之差, 若是当前元素不存在下一个更高温度的元素, 则这个位置用0代替; 2. 思路 本题用单调栈来求解;单调栈就适用于来求当前元素左边或者右边第一个比当前元素大或者小的元素;【单调栈:让栈中的元素保持单调

SpringMVC的第一个案例 Helloword 步骤

第一步:web.xml配置 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocati