普通数组-----缺失的第一个正数

🔥个人主页: Milestone-里程碑

❄️个人专栏: <<力扣hot100>> <<C++>><<Linux>>

<<Git>><<MySQL>>

🌟心向往之行必能至

题目解析

这道题要求在一个未排序的整数数组中,找出没有出现的最小正整数,并且需要满足两个严格的条件:

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)(常数级额外空间)

直接排序或使用哈希表的方法,要么时间复杂度不达标,要么空间复杂度不达标。因此,我们需要采用一种巧妙的原地置换策略,利用数组本身作为哈希表来解决问题。

核心思路

对于一个长度为 n 的数组,缺失的最小正整数只可能在 [1, n+1] 范围内:

  • 如果 [1, n] 内的所有整数都出现了,那么缺失的就是 n+1
  • 否则,缺失的就是 [1, n] 中第一个未出现的数。

我们的目标就是把数组中所有在 [1, n] 范围内的数,放到它们 "应该" 在的位置上,即数值 k 应该放在索引 k-1 的位置上。这样,我们只需要遍历一次数组,找到第一个位置 i 上的数不等于 i+1i+1 就是我们要找的答案。

详细步骤

  1. 原地置换 :遍历数组,对于每个元素 nums[i],如果它是一个在 [1, n] 范围内的正整数,并且它没有在正确的位置 nums[i]-1 上,就将它与 nums[nums[i]-1] 交换,直到当前位置的元素正确或超出范围为止。
  2. 查找缺失 :再次遍历数组,检查每个位置 i。如果 nums[i] != i+1,说明 i+1 就是缺失的最小正整数。
  3. 全包含 :如果遍历结束后所有位置都正确,说明 [1, n] 都存在,返回 n+1

完整代码

cpp

复制代码
class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        // 第一步:原地置换,将[1, n]范围内的数放到正确位置
        for (int i = 0; i < n; ++i) {
            // 当nums[i]在[1, n]范围内,且不在正确位置时,进行交换
            while (1 <= nums[i] && nums[i] <= n && nums[i] != nums[nums[i] - 1]) {
                int j = nums[i] - 1; // 计算正确的位置索引
                swap(nums[i], nums[j]); // 交换到正确位置
            }
        }
        
        // 第二步:遍历查找第一个缺失的正整数
        for (int i = 0; i < n; ++i) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }
        
        // 如果[1, n]都存在,返回n+1
        return n + 1;
    }
};

复杂度分析

  • 时间复杂度 :O(n)
    • 虽然有两层循环,但每个元素最多被交换到其正确的位置一次,因此总的交换次数是 O (n)。两次线性遍历也是 O (n),所以整体时间复杂度为 O (n)。
  • 空间复杂度 :O(1)
    • 我们只在原数组上进行操作,没有使用额外的辅助空间,满足了常数级空间复杂度的要求。

示例演示

nums = [3, 4, -1, 1] 为例:

  1. 初始数组:[3, 4, -1, 1]
  2. 处理 i=0nums[0]=3,应在位置 2,交换后数组变为 [-1, 4, 3, 1]
  3. 处理 i=1nums[1]=4,应在位置 3,交换后数组变为 [-1, 1, 3, 4]
  4. 处理 i=1nums[1]=1,应在位置 0,交换后数组变为 [1, -1, 3, 4]
  5. 处理 i=2nums[2]=3,已在正确位置;i=3nums[3]=4,已在正确位置。
  6. 最终数组:[1, -1, 3, 4]
  7. 遍历查找,发现 i=1nums[1] != 2,所以返回 2
相关推荐
三毛的二哥5 小时前
BEV:典型BEV算法总结
人工智能·算法·计算机视觉·3d
南宫萧幕6 小时前
自控PID+MATLAB仿真+混动P0/P1/P2/P3/P4构型
算法·机器学习·matlab·simulink·控制·pid
故事和你917 小时前
洛谷-数据结构1-4-图的基本应用1
开发语言·数据结构·算法·深度优先·动态规划·图论
我叫黑大帅7 小时前
为什么map查找时间复杂度是O(1)?
后端·算法·面试
炽烈小老头8 小时前
【每天学习一点算法 2026/04/20】除自身以外数组的乘积
学习·算法
skilllite作者8 小时前
AI agent 的 Assistant Auto LLM Routing 规划的思考
网络·人工智能·算法·rust·openclaw·agentskills
破浪前行·吴9 小时前
数据结构概述
数据结构·学习
深圳市九鼎创展科技9 小时前
MT8883 vs RK3588 开发板全面对比:选型与场景落地指南
大数据·linux·人工智能·嵌入式硬件·ubuntu
py有趣10 小时前
力扣热门100题之不同路径
算法·leetcode
_日拱一卒10 小时前
LeetCode:25K个一组翻转链表
算法·leetcode·链表