news 2026/6/23 19:15:53

LeetCode 41题实战:用‘原地哈希’在O(n)内找出缺失的最小正整数(附C++/Python代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 41题实战:用‘原地哈希’在O(n)内找出缺失的最小正整数(附C++/Python代码)

LeetCode 41题实战:原地哈希算法在O(n)时间找出缺失的最小正整数

刷算法题时,我们常常会遇到一类经典问题:在给定的整数数组中找出缺失的最小正整数。这类问题看似简单,但要在O(n)时间内且不使用额外空间解决,就需要一些巧妙的技巧。今天我们就来深入探讨LeetCode第41题"缺失的第一个正数",并重点解析"原地哈希"这一精妙解法。

1. 问题理解与初步分析

给定一个未排序的整数数组,找出其中没有出现的最小的正整数。要求算法的时间复杂度为O(n),并且只能使用常数级别的额外空间。

举个例子:

  • 输入:[3,4,-1,1]
  • 输出:2
  • 解释:数组中包含1、3、4,但缺少2

关键约束条件

  • 时间复杂度O(n)
  • 空间复杂度O(1)
  • 数组可能包含负数和重复值
  • 数组长度可能很大

提示:面试中遇到这类问题,首先要明确问题的边界条件和约束,这是解题的第一步。

2. 原地哈希算法原理

原地哈希(In-place Hashing)是一种在不使用额外空间的情况下,利用输入数组本身作为哈希表的技术。其核心思想是通过重新排列数组元素,使得每个元素的值与其索引之间存在某种对应关系。

对于本题,我们可以利用以下观察:

  1. 缺失的最小正整数一定在1到n+1之间(n为数组长度)
  2. 我们可以将数组视为哈希表,通过交换元素使得nums[i] = i+1

算法步骤概述

  1. 遍历数组,将每个正整数x放到它应该在的位置(即索引x-1处)
  2. 再次遍历数组,第一个不满足nums[i] = i+1的位置i,对应的i+1就是缺失的最小正整数
  3. 如果所有位置都满足条件,则缺失的是n+1

3. 详细实现步骤与边界处理

让我们用C++和Python分别实现这个算法,并详细讨论各种边界情况的处理。

3.1 C++实现

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; }

关键点解析

  1. 使用while循环而不是if,确保交换后的新元素也被正确处理
  2. 交换条件nums[nums[i]-1] != nums[i]避免无限循环
  3. 处理完所有元素后,只需线性扫描找出第一个不匹配的位置

3.2 Python实现

def firstMissingPositive(nums): n = len(nums) for i in range(n): while 1 <= nums[i] <= n and nums[nums[i]-1] != nums[i]: nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1] for i in range(n): if nums[i] != i + 1: return i + 1 return n + 1

Python实现特点

  1. 利用Python的多重赋值特性简化交换操作
  2. 条件判断更加简洁直观
  3. 整体结构与C++版本高度一致

3.3 边界情况处理

在实际编码中,我们需要特别注意以下几种边界情况:

边界情况处理方法示例输入预期输出
包含负数跳过不处理[-1, -2, 0]1
包含重复值避免无限循环[1, 1]2
所有数都连续返回n+1[1, 2, 3]4
空数组直接返回1[]1

4. 算法复杂度分析

让我们从时间和空间两个维度分析这个算法的性能:

时间复杂度

  • 表面看有两层循环,但每个元素最多被交换一次到正确位置
  • 因此总体时间复杂度是O(n)

空间复杂度

  • 只使用了常数级别的额外空间(几个临时变量)
  • 满足O(1)的要求

性能对比表

方法时间复杂度空间复杂度适用场景
排序后扫描O(nlogn)O(1)无空间限制
哈希表O(n)O(n)可接受额外空间
原地哈希O(n)O(1)严格空间限制

5. 面试技巧与常见问题

在技术面试中,这类问题常常被用来考察候选人对基础算法的理解和编码能力。以下是一些实用的面试技巧:

  1. 先沟通再编码:不要直接开始写代码,先和面试官确认问题细节和约束条件
  2. 举例说明:用具体例子解释你的思路,这有助于面试官理解你的思考过程
  3. 考虑边界:主动讨论各种边界情况,展示你的全面思考
  4. 代码风格:写出清晰、模块化的代码,适当添加注释

常见面试问题

  • 如何证明这个算法是正确的?
  • 为什么使用while循环而不是if?
  • 如果数组中有重复元素会怎样?
  • 这个算法能否处理非常大的数组?

6. 实际应用与扩展

原地哈希算法不仅适用于这道LeetCode题目,它在许多其他场景也有广泛应用:

  1. 寻找重复元素:如LeetCode 287题"寻找重复数"
  2. 数组重排列:如将数组排序为波浪形
  3. 缺失多个数字:扩展问题,找出所有缺失的数字

进阶挑战

  • 尝试修改算法,使其能找出前k个缺失的正整数
  • 思考如何在不修改原数组的情况下解决问题(虽然会增加空间复杂度)
  • 研究其他使用原地算法的经典问题,如Dutch National Flag问题

在实际工程项目中,这类算法思想也有其用武之地,特别是在内存受限的嵌入式系统或处理大规模数据时,原地算法能显著减少内存开销。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 19:15:31

解锁PCIe P2P直通:深入解析ACS重定向关闭与iATU配置实战

1. PCIe P2P直通技术基础 PCIe P2P&#xff08;Peer-to-Peer&#xff09;直通技术是高性能计算和存储系统中的关键优化手段。简单来说&#xff0c;它允许两个PCIe端点设备&#xff08;比如GPU和NVMe SSD&#xff09;直接交换数据&#xff0c;完全绕开CPU和系统内存这个"中…

作者头像 李华
网站建设 2026/6/23 19:15:48

告别手动操作:用Python自动化COMSOL仿真的3个关键突破

告别手动操作&#xff1a;用Python自动化COMSOL仿真的3个关键突破 【免费下载链接】MPh Pythonic scripting interface for Comsol Multiphysics 项目地址: https://gitcode.com/gh_mirrors/mp/MPh 你是否也曾为COMSOL的重复性仿真任务感到疲惫&#xff1f;每天花费数小…

作者头像 李华
网站建设 2026/6/23 19:15:51

ADI SHARC 21489 DSP Flash编程与烧写实战指南

1. 项目概述&#xff1a;从调试到固化的必经之路在ADI SHARC 21489这类高性能DSP的开发流程里&#xff0c;我们通常会把大部分精力花在算法实现、代码调试和性能优化上。当你在VisualDSP&#xff08;VDSP&#xff09;里看着程序在线运行一切正常&#xff0c;LED灯随着你的指令闪…

作者头像 李华
网站建设 2026/6/23 19:16:11

2026年最新攻略 孩子英语听力差用什么软件能稳步提升

做了快6年英语听力领域的教研&#xff0c;最近后台被问爆的一个问题就是&#xff1a;2026年了&#xff0c;孩子英语听力总是拖后腿&#xff0c;刷了半本题库也没见进步&#xff0c;到底用什么软件能真的稳步提升&#xff1f; 先给大家泼个冷水&#xff1a;现在市面上80%的听力软…

作者头像 李华