41. 缺失的第一个正数

本文详细介绍了两种O(n)时间复杂度的算法,用于解决寻找未排序整数数组中缺失的第一个正整数的问题。方法一是通过维护两个指针l和r,动态调整数组结构;方法二是通过迭代将元素放到正确位置,逐步接近理想状态。两种方法均通过了所有测试用例,展示了高效的空间和时间效率。
摘要由CSDN通过智能技术生成

41. 缺失的第一个正数

题目描述

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

进阶:你可以实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案吗?

示例1:

输入:nums = [1,2,0]
输出:3

示例2:

输入:nums = [3,4,-1,1]
输出:2

示例3:

输入:nums = [7,8,9,11,12]
输出:1

提示:

  • 0 ≤ n u m s . l e n g t h ≤ 300 0 \le nums.length \le 300 0nums.length300
  • − 2 31 ≤ n u m s [ i ] ≤ 2 31 − 1 -2^{31} \le nums[i] \le 2^{31} - 1 231nums[i]2311

题解:
法一:

核心思想:

理想情况下,长度为 nnums 应该正好包含 1~n ,如果某个元素 nums[i] 不在范围内,那么在理想情况下,nums 包含的范围应该相应的减小。数组的长度和元素范围是相对应的。

  • 使用两个变量 lr

    1. l 表示遍历到目前为止,nums 已经包含的正整数范围是 [1,l] ,开始时 l = 0 ,表示没有包含任何正整数

    2. r 表示遍历到目前为止,后续出现最优状况的情况下,nums 可能包含的正整数范围是 [1,r] ,开始时 r = n ,因为还没开始遍历,所有以后续出现的最优状况是 num 包含 1~n 所有的整数。r 同时表示 nums 当前的结束位置。

  • 从左往右遍历 nums ,遍历到位置 l ,此时已经包含的正整数范围是 [1, l] ,而在后续最优的情况下,nums 可能包含的正整数范围是 [1, r] ,所以当前需要的元素范围是 [l + 1, r] ,分情况讨论:

    1. nums[l] == l + 1 ,说明此时 nums 包含的正整数范围可以扩到 [1, l + 1] ,所以 l++
    2. nums[l] <= l ,此时说明 [l + 1, r] 范围上的数少了一个,所以在 nums 后续最优的情况下,可能包含的正整数范围缩小为 [1, r - 1] ,此时把 nums[r - 1] 位置上的数放到位置 l 上,下一步检查这个元素,并且 r--
    3. nums[l] > r ,与 2 同理
    4. num[num[l] - 1] == nums[l] ,在步骤 2 和 3 中没中,说明 nums[l][l + 1, r] 范围内,而且这个数应该在 nums[l] - 1 位置上,而此时出现 num[num[l] - 1] == nums[l] ,说明出现了两个 nums[l] ,既然 [l + 1, r] 上出现了重复元素,说明 [l + 1, r] 范围上少了一个数,操作同步骤 2 和 3
    5. 若步骤 2、3、4 都没中,说明发现了 [l + 1, r] 范围上的数,并且此时未发现重复,则 nums[l] 应该放在 nums[l] - 1 位置上,交换 lnums[l] - 1 位置上的元素,继续判断 l 位置上的元素
  • 最终 lr 会碰在一起,nums 已经包含的正整数范围是 [1, l] ,返回 l + 1 即可

法一代码:

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int l = 0, r = nums.size();
        while ( l < r ) {
            if ( nums[l] == l + 1 ) ++l;
            else if ( nums[l] <= l || nums[l] > r || nums[nums[l] - 1] == nums[l] ) 
                swap(nums[l], nums[--r] );
            else swap( nums[l], nums[nums[l] - 1]);
        }
        return l + 1;
    }
};
/*
时间:0ms,击败:100.00%
内存:9.4MB,击败:97.55%
*/
法二:

假设 nums 长度为 n ,理想的情况是 nums 的所有元素正好包括 1~n 并且 nums[i] == i + 1 ,这种情况我们很容易知道未出现的最小正整数是什么。

但是仅仅限于 理想 情况。虽然元素是无序的,但我们知道了什么情况下最容易找到未出现的最小正整数,我们可以向这种 理想 情况转换,具体操作:若 1 <= nums[i] <= nnums[i] != nums[nums[i] - 1] ,我们应该将其放到 nums[nums[i] - 1] 位置。假设所有 1~n 范围内的元素都放在正确的位置,剩下的就是从前往后遍历找到第一个 nums[i] != i + 1 的位置,i + 1 就是我们想要的答案。

法二代码:

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for( int i = 0; i < n; ++i ) {
            while ( nums[i] >= 1 && nums[i] <= n && nums[i] != nums[nums[i] - 1] )
                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;
    }
};
/*
时间:0ms,击败:100.00%
内存:9.3MB,击败:99.55%
*/

两种方法均用到了一个关键思想 nums[i] 放到其应该待的地

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值