LeetCode 268 Missing Number 缺失数字全解:排序、哈希集合、位运算 XOR 与数学求和四种解法对比

发布时间:2026/11/11 3:16:29

LeetCode 268 Missing Number 缺失数字全解:排序、哈希集合、位运算 XOR 与数学求和四种解法对比 LeetCode 268 Missing Number 缺失数字全解排序、哈希集合、位运算 XOR 与数学求和四种解法对比【免费下载链接】leetcodeLeetcode solutions项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode导读Missing Number缺失数字是 LeetCode 上经典的数组入门题给定一个包含n个互不相同数字的数组数字取自[0, n]区间其中恰好缺失一个数字要求找出它。本仓库以 articles/missing-number.md 为主干完整收录了排序、哈希集合、位运算 XOR 与数学求和四种解法并在 python/、cpp/、go/、rust/、javascript/ 等十余种语言目录下提供了对应实现如 cpp/0268-missing-number.cpp、python/0268-missing-number.py。读完本文你将掌握这道题的四种解题思路、时间复杂度对比以及常见的边界陷阱能够举一反三地迁移到其他查找缺失/重复元素类问题。前置知识在动手解决本题之前建议先熟悉以下三个基础概念它们是文中四种解法的底层支撑位运算 XOR异或XOR 解法利用a ^ a 0的性质让所有成对出现的数字互相抵消最终只剩下缺失的那个数字。数学求和公式数学解法利用0到n连续整数的求和公式用期望总和减去数组实际总和得到缺失值。哈希集合Hash Set哈希解法利用集合的常数时间查找能力快速判断[0, n]中哪个数字没有出现在数组里。仓库中的 hints/missing-number.md 给出了官方的进阶提示脉络从暴力O(n²)的逐个比对到用哈希集合优化为O(n)时间再到用位运算进一步把空间压缩到O(1)完整呈现了从朴素到最优的思维进化路径。问题定义与边界条件数组长度为n其中包含n个互不相同的数字全部取自区间[0, n]。由于区间内有n 1个整数而数组只有n个元素因此恰好缺失一个数字。关键边界条件有两个缺失数字可能是n本身。例如nums [0, 1]n 2缺失的是2也就是n。任何只遍历索引0到n - 1的解法都会漏掉这个答案。数组是无序的。输入并不保证排序因此排序解法必须显式先排序其他解法则完全不受顺序影响。仓库 cpp/0268-missing-number.cpp 的注释中用两个例子说明了这一设定nums [3, 0, 1]缺失2nums [0, 1]缺失2。解法一排序Sorting核心直觉如果数组是完整且有序的那么索引i位置上的值应当恰好等于i。一旦出现nums[i] ! i这个索引i就是缺失的数字。排序把乱序数组排好让这个对比变得直观是最适合初学者理解的做法。算法步骤将数组按升序排序。从索引0遍历到n - 1若nums[i] ! i说明i缺失直接返回i。若所有索引都与值匹配说明缺失的是n返回n。以nums [3, 0, 1]为例排序后为[0, 1, 3]i 0时nums[0] 0i 1时nums[1] 1i 2时nums[2] 3 ! 2返回2。多语言实现class Solution: def missingNumber(self, nums: List[int]) - int: n len(nums) nums.sort() for i in range(n): if nums[i] ! i: return i return nclass Solution { public: int missingNumber(vectorint nums) { int n nums.size(); sort(nums.begin(), nums.end()); for (int i 0; i n; i) { if (nums[i] ! i) { return i; } } return n; } };public class Solution { public int missingNumber(int[] nums) { int n nums.length; Arrays.sort(nums); for (int i 0; i n; i) { if (nums[i] ! i) { return i; } } return n; } }class Solution { /** * param {number[]} nums * return {number} */ missingNumber(nums) { let n nums.length; nums.sort((a, b) a - b); for (let i 0; i n; i) { if (nums[i] ! i) { return i; } } return n; } }func missingNumber(nums []int) int { n : len(nums) sort.Ints(nums) for i : 0; i n; i { if nums[i] ! i { return i } } return n }impl Solution { pub fn missing_number(nums: Veci32) - i32 { let n nums.len() as i32; let mut nums nums; nums.sort(); for i in 0..nums.len() { if nums[i] ! i as i32 { return i as i32; } } n } }仓库中 C、C#、Kotlin、Swift 等语言的排序实现同样遵循这一模式可分别参考 c/0268-missing-number.c、csharp/0268-missing-number.cs、kotlin/0268-missing-number.kt、swift/0268-missing-number.swift。复杂度分析时间复杂度$O(n \log n)$主要开销来自排序。空间复杂度$O(1)$ 或 $O(n)$取决于排序算法是否使用额外空间。解法二哈希集合Hash Set核心直觉核心问题是能否快速判断某个数字是否存在于数组中。把数组元素全部放入哈希集合后对任意数字的成员判断都能在常数时间内完成。随后只需在[0, n]范围内逐个检查第一个不在集合中的数字就是答案。这种做法用少量额外空间换来了非常清晰简单的逻辑。算法步骤将数组所有元素插入哈希集合。遍历0到n的所有数字若某个数字不在集合中返回它作为缺失数字。因为恰好只有一个数字缺失该过程必然找到答案。多语言实现class Solution: def missingNumber(self, nums: List[int]) - int: num_set set(nums) n len(nums) for i in range(n 1): if i not in num_set: return iclass Solution { public: int missingNumber(vectorint nums) { unordered_setint num_set(nums.begin(), nums.end()); int n nums.size(); for (int i 0; i n; i) { if (num_set.find(i) num_set.end()) { return i; } } return -1; } };func missingNumber(nums []int) int { numSet : make(map[int]struct{}) for _, num : range nums { numSet[num] struct{}{} } n : len(nums) for i : 0; i n; i { if _, exists : numSet[i]; !exists { return i } } return -1 }其余语言的实现大同小异Java 使用HashSetJavaScript 使用SetKotlin 使用nums.toSet()Swift 使用Set(nums)Rust 使用HashSeti32收集迭代器此处不再逐一展开。注意循环上界是n含因为n本身可能是缺失值。复杂度分析时间复杂度$O(n)$插入与查询均为常数时间。空间复杂度$O(n)$用于存储哈希集合。解法三位运算 XORBitwise XOR核心直觉XOR 拥有三个关键性质a ^ a 0数字与自己异或抵消a ^ 0 aXOR 满足交换律与结合律运算顺序无关紧要因此把0到n的全部数字与数组中的全部数字一起异或每个在两边都出现的数字都会成对抵消最终剩下的只有缺失的那个数字。该方案无需排序也无需额外数据结构即可在线性时间、常数空间内求解。仓库 cpp/0268-missing-number.cpp 顶部注释用nums [0, 1, 3, 4]推导了完整过程Missing 4^(0^0)^(1^1)^(2^3)^(3^4) (4^4)^(0^0)^(1^1)^(3^3)^2 0^0^0^0^2 2这正是a ^ a 0与交换结合律的直观体现。算法步骤令n为数组长度。初始化变量xorr n先纳入缺失候选值n。遍历i从0到n - 1xorr ^ ixorr ^ nums[i]循环结束后xorr即缺失数字返回它。多语言实现class Solution: def missingNumber(self, nums: List[int]) - int: n len(nums) xorr n for i in range(n): xorr ^ i ^ nums[i] return xorrclass Solution { public: int missingNumber(vectorint nums) { int n nums.size(); int xorr n; for (int i 0; i n; i) { xorr ^ i ^ nums[i]; } return xorr; } };impl Solution { pub fn missing_number(nums: Veci32) - i32 { let n nums.len() as i32; let mut xorr n; for i in 0..nums.len() { xorr ^ i as i32 ^ nums[i]; } xorr } }/** * https://leetcode.com/problems/missing-number/ * Time O(N) | Space O(1) * param {number[]} nums * return {number} */ var missingNumber function (nums, missingNumber nums.length) { for (let i 0; i nums.length; i) { const xor i ^ nums[i]; missingNumber ^ xor; } return missingNumber; };仓库中的 rust/0268-missing-number.rs 与 javascript/0268-missing-number.js 采用了完全相同的 XOR 策略其中 JavaScript 版本利用默认参数把n直接作为missingNumber的初始值写法更为紧凑。复杂度分析时间复杂度$O(n)$单次线性遍历。空间复杂度$O(1)$仅使用一个整型变量。解法四数学求和Math核心直觉数学观察非常简洁0到n的连续整数之和是已知的。用期望总和减去数组实际元素之和差值就是缺失的数字。为避免分别计算两个总和可能带来的溢出问题可以在单次循环中边加边减res初始为n每轮先加i再减nums[i]循环结束后res即为答案。这样既保持了逻辑干净又在部分语言中规避了溢出风险。算法步骤令n为数组长度。初始化变量res n。遍历i从0到n - 1res ires - nums[i]循环结束后res即缺失数字返回它。多语言实现class Solution: def missingNumber(self, nums: List[int]) - int: res len(nums) for i in range(len(nums)): res i - nums[i] return resfunc missingNumber(nums []int) int { res : len(nums) for i : 0; i len(nums); i { res i - nums[i] } return res }public class Solution { public int missingNumber(int[] nums) { int res nums.length; for (int i 0; i nums.length; i) { res i - nums[i]; } return res; } }class Solution { func missingNumber(_ nums: [Int]) - Int { var res nums.count for i in 0...nums.count-1 { res i - nums[i] } return res } }仓库中的 python/0268-missing-number.py 与 go/0268-missing-number.go 正是该单循环边加边减写法的实现。需要注意的是java/0268-missing-number.java 选择了另一种等价写法先计算total n * (n 1) / 2再减去数组和sum得到答案——这对应原文档中提到的先算完整期望和的版本在n极大时存在溢出风险需结合语言整数类型谨慎使用。复杂度分析时间复杂度$O(n)$。空间复杂度$O(1)$。常见陷阱Common Pitfalls陷阱一忘记n本身可能就是缺失值数组长度为n取值范围是[0, n]因此n本身也可能缺失。只检查索引0到n - 1的解法会在其他数字全部齐全时漏掉n无法返回正确答案。四种解法都通过循环结束后返回n或初始值设为n的方式覆盖了这一情况。陷阱二求和方案的整数溢出使用数学方法时若先单独计算完整期望和n * (n 1) / 2再相减当n很大时可能发生整数溢出。把加法和减法合并到同一个循环中res i - nums[i]可有效规避该问题这也是原文档推荐单循环写法的原因。若必须使用两段式写法如 java/0268-missing-number.java应确认语言整数类型能容纳n * (n 1)的上限。四种解法对比总结解法核心思想时间复杂度空间复杂度是否原地适用场景排序排好序后比较nums[i]与i$O(n \log n)$$O(1)$ 或 $O(n)$取决于排序算法初学者理解有序对比哈希集合集合常数时间成员查询$O(n)$$O(n)$否逻辑最清晰直观位运算 XOR成对抵消、仅剩缺失值$O(n)$$O(1)$是面试最优解兼顾时间与空间数学求和期望和减实际和$O(n)$$O(1)$是无位运算偏好的语言从仓库 hints/missing-number.md 的建议来看本题的目标是达到$O(n)$ 时间、$O(1)$ 空间即 XOR 与数学求和两种方案。它们不需要任何额外数据结构是面试与竞赛场景下的首选排序方案胜在直观哈希集合方案胜在思路通用都是理解进阶解法之前的重要铺垫。延伸阅读本题的思想可迁移到仓库内多道相关题目articles/find-all-numbers-disappeared-in-an-array.md[1, n]范围内可能出现多个缺失数字需借助下标标记技巧。articles/set-mismatch.md在一个缺失 一个重复的场景下XOR 与数学技巧依然适用。articles/first-missing-positive.md在任意数组中找第一个缺失正整数将值 ↔ 下标映射发挥到极致。articles/missing-element-in-sorted-array.md 与 articles/missing-number-in-arithmetic-progression.md在有序或等差背景下用二分查找定位缺失元素。阅读时建议对照各语言目录下的0268-missing-number.*文件如 c/0268-missing-number.c、typescript/0268-missing-number.ts、ruby/0268-missing-number.rb体会同一算法在不同语言生态中的惯用写法从而真正把思路内化为代码。【免费下载链接】leetcodeLeetcode solutions项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/8 7:33:08

企业为何要自建大模型?从数据安全到微调落地的全面解析

1. 先别急着站队:这个问题背后藏着一个真实困境我在很多技术社群和客户现场都遇到过同一个问题——公用大模型的能力已经强到“乱杀”了,一个API接进来,写文案、改代码、做翻译、抽信息样样都行,为什么还要花大价钱买GPU、组团队、…

2026/11/8 5:27:44

HHFT:异构层级特征的两级自注意力推荐模型

推荐系统做到一定阶段,多数团队都会撞上一堵墙:模型的离线指标怎么调都涨不动了,特征该加的也加了,样本量也够大,但AUC就是卡在某个数位上。这时候问题往往不在特征的数量,而在特征的组织方式。HHFT&#x…

2026/11/9 1:42:55

AI论文写作工具对比:千笔与锐智AI的核心技术与应用

1. 项目背景与核心价值作为一名经历过自考论文写作的过来人,我深知在工作和学习双重压力下完成学术论文的艰辛。2026年最新推出的这两款AI论文写作工具——千笔和锐智AI,正是为解决这个痛点而生。它们不仅仅是简单的文字生成器,而是整合了学术…

2026/11/11 5:02:49

电工证可入户厦门吗?真实经历告诉你外省证怎么转

电工证可入户厦门吗?真实经历告诉你外省证怎么转 之前考的证在外省能不能转过来?这是我最近接到的咨询最多的问题之一。很多人在外地考了电工证,现在想回厦门发展,但又担心证书不能用,入户更是遥不可及。今天我就用自己和身边人的真实经历,帮你理清楚电…

2026/11/11 5:02:49

沧州市电工证办理值不值得考?别再犹豫了,看完这篇就懂

沧州市电工证办理值不值得考?别再犹豫了,看完这篇就懂 你是不是正愁找不到工作?是不是被用人单位要求必须有特种作业操作证才能上岗?别急,今天咱们就来聊聊【沧州市电工证办理】值不值得考,以及怎么考才不走弯路。…

2026/11/11 5:02:48

学校电工证年审要多久?2026河南最新政策怎么应对

学校电工证年审要多久?2026河南最新政策怎么应对 怕考不过白交培训费?别急,今天我就给你讲讲【学校电工证年审要多久】这件事,尤其是2026河南最新政策下,你该怎么操作,避免被坑,省下冤枉钱。…

2026/11/11 5:02:48

贵港电工证办理流程6怎么考网上查询

贵港电工证办理流程6怎么考网上查询 之前考的证在外省能不能转过来?这个确实是很多人在考电工证前最关心的问题,尤其是那些已经在外地考了证但想回老家发展的朋友。其实现在国家推行“全国一体化政务服务平台”,很多证书 网上查询 都可以操作,…

2026/11/11 5:02:48

在哪办电工证考试真题与备考技巧

电工证怎么考?郑州报考避坑指南全解析 你是不是也遇到过这种情况:证书快到期了,却不知道怎么复审?一查才发现自己差点就“裸奔”上岗了。别慌,今天我们就来聊聊【在哪办电工证】的那些事儿,特别是郑州的朋友们,更要仔细看看这个【郑州报考避坑指南】,…

2026/11/11 4:57:47

电工证能联网吗千万别踩坑 这些报名避坑指南必须看

电工证能联网吗千万别踩坑 这些报名避坑指南必须看 你是不是正愁不知道去哪报名电工证,怕被中介坑?别急,今天就给你讲讲【电工证能联网吗】这事到底咋回事,还有那些你必须知道的报名避坑指南。我干这行快十年了,见过太多人因为选错地方、听信谣言,结果…

2026/11/10 8:12:38

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/11 0:02:26

考低压电工证通过率考试真题与备考技巧

低压电工证通过率高不高?学历不高也能考,值不值得考? 你是不是总听说电工证能帮你找高薪工作,但又担心自己学历不够,考不上?其实,低压电工证考试门槛并没有你想象中那么高,关键是方法对不对。这篇文章就告诉你, 考低压电工证通过率到底有多高 ,…

2026/11/11 0:02:26

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名 你是不是也和我一样,刚毕业就听说低压电工证学时必须达标才能上岗?可一打听,发现报名机构五花八门,价格参差不齐, 不知道去哪报名怕被中介坑…

2026/11/10 20:08:15

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑