news 2026/7/1 20:11:39

【码道初阶】Leetcode136:只出现一次的数字:异或一把梭 vs HashMap 计数(两种解法完整复盘)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【码道初阶】Leetcode136:只出现一次的数字:异或一把梭 vs HashMap 计数(两种解法完整复盘)

只出现一次的数字:异或一把梭 vs HashMap 计数(两种解法完整复盘)

题目给一个非空整数数组nums
除了某个元素只出现一次外,其余每个元素都出现两次。要求找出那个只出现一次的元素。

并且有两个硬要求:

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

这两个条件决定了解法的优先级:能满足 O(1) 空间的只有位运算这条路最合适。当然,用 HashMap 计数也能过,但属于“能做但不符合空间约束”的思路。


解法一:异或 XOR(满足题目所有限制,最佳解)

代码

classSolution{publicintsingleNumber(int[]nums){intres=0;for(intx:nums){res^=x;}returnres;}}

关键思路:把数组所有数异或起来

异或(XOR,记作^)有三个非常重要的性质:

  1. a ^ a = 0(相同的数异或为 0)
  2. a ^ 0 = a(任何数和 0 异或还是它自己)
  3. 异或满足交换律和结合律:
    a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b

题目里“其余元素都出现两次”,这意味着:

  • 每个出现两次的数,最终都会在异或中“互相抵消”变成 0
  • 只出现一次的那个数没有配对,最后会“剩下来”

所以把所有数从头到尾异或一遍,最终结果就是答案。

用示例走一遍(直觉会更牢)

[4,1,2,1,2]

  • res = 0
  • res ^= 4→ 4
  • res ^= 1→ 4^1
  • res ^= 2→ 412
  • res ^= 1→ 4(11)^2 = 402 = 4^2
  • res ^= 2→ 4(22) = 4^0 = 4

答案就是 4。

复杂度

  • 时间:O(n)(一次遍历)
  • 空间:O(1)(只用了一个整数 res)

这个解法为什么“非常干净”

因为它不关心数值大小、正负、顺序,只依赖“出现两次就抵消”的结构。题目条件越严格,这种解法越显得漂亮。


解法二:HashMap 计数(通用但不满足 O(1) 空间)

代码

classSolution{publicintsingleNumber(int[]nums){HashMap<Integer,Integer>hashnums=newHashMap<>();for(inti=0;i<nums.length;i++){hashnums.put(nums[i],hashnums.getOrDefault(nums[i],0)+1);}for(inti=0;i<nums.length;i++){if(hashnums.get(nums[i])==1)returnnums[i];}return-1;}}

关键思路:统计每个数字出现次数

这条路的思路非常直观:

  1. 第一遍遍历:用 HashMap 记录每个数字出现的次数
  2. 第二遍遍历:找到计数为 1 的那个数字并返回

这里用到了一个很实用的 API:

  • getOrDefault(key, 0):如果 key 不存在,就当它出现过 0 次
  • V getOrDefault(Object key, V defaultValue)返回 key 对应的 value,key 不存在,返回默认值
  • 所以这里的意思是,如果Key不存在,就初始化其value为0+1;如果Key存在,其value为原值+1
  • 与本专栏的Leetcode387一个道理

复杂度

  • 时间:两次遍历都是O(n),总的还是O(n)
  • 空间:最坏情况下 HashMap 需要存所有不同数字,空间O(n)

这条路的优点

  • 思路直接、可扩展:
    如果题目改成“出现一次,其余出现三次/五次/不固定次数”,HashMap 基本都能通吃。
  • 读代码非常直观,不需要位运算基础。

这条路的缺点

  • 不满足题目要求的“常量额外空间”
  • 还有装箱开销(int → Integer),HashMap 本身也有较大的常数开销

两种解法对比(从多个维度看差异)

1)是否满足题目硬性要求

  • 异或:✅O(n)时间 + ✅O(1)空间(完全满足)
  • HashMap:✅O(n)时间 + ❌O(n)空间(不满足)

2)性能与常数开销

  • 异或:只做整数运算,CPU 级别快,内存压力极小
  • HashMap:哈希计算、扩容、对象装箱、内存访问更重,常数开销明显更大

3)可扩展性

  • 异或:只适用于“其他都出现两次”的结构(非常精准)
  • HashMap:更通用,条件一变也能继续用

4)表达题目结构的能力

  • 异或:把“成对出现抵消”的数学结构直接写进代码里,属于“对症下药”
  • HashMap:属于“统计学做法”,能做但有点“用力过猛”

总结

这题最推荐的写法就是异或:

  • 一次遍历
  • 常量空间
  • 代码短到几乎没有出错空间
  • 完全契合题目约束

HashMap 解法也能正确输出答案,但它的角色更像是“通用备胎”:当题目不要求 O(1) 空间,或者题目条件更复杂时,它会更顺手;而在本题这种强约束场景下,异或才是标准答案。

如果想进一步进阶,可以顺着这题继续看两个经典变体:

  • “除了一个数出现一次,其余出现三次”
  • “两个数出现一次,其余出现两次”
    它们都是位运算体系里非常漂亮的延伸。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 13:50:26

Dify平台与低代码平台如若依、JeecgBoot集成方案设想

Dify平台与低代码平台如若依、JeecgBoot集成方案设想 在企业数字化转型的浪潮中&#xff0c;一个明显的矛盾正在浮现&#xff1a;业务系统建设的速度越来越快&#xff0c;而智能化升级的脚步却相对迟缓。我们已经可以用若依或 JeecgBoot 在一天之内搭建起一套完整的资产管理系统…

作者头像 李华
网站建设 2026/6/30 3:36:02

Ruoyi-AI终极指南:零代码部署AI应用的快速实战方案

Ruoyi-AI终极指南&#xff1a;零代码部署AI应用的快速实战方案 【免费下载链接】ruoyi-ai 基于ruoyi-plus实现AI聊天和绘画功能-后端 本项目完全开源免费&#xff01; 后台管理界面使用elementUI服务端使用Java17SpringBoot3.X 项目地址: https://gitcode.com/GitHub_Trendin…

作者头像 李华
网站建设 2026/7/1 13:50:29

核心要点:上位机在无线通信协议中的实现方式

上位机在无线通信系统中的角色与实战实现你有没有遇到过这样的场景&#xff1a;几个传感器节点分布在工厂各处&#xff0c;数据怎么汇总&#xff1f;设备出了故障&#xff0c;如何远程查看状态、下发指令&#xff1f;这时候&#xff0c;“上位机”这个词就会频繁出现。但“上位…

作者头像 李华
网站建设 2026/7/1 17:04:40

OBS StreamFX插件终极指南:5分钟打造影院级直播画面

还在为直播间画面平淡无奇而烦恼吗&#xff1f;想让你的直播拥有电影大片般的视觉效果吗&#xff1f;今天我要为你介绍这款能让OBS直播效果瞬间升级的神器——StreamFX插件&#xff01;这款完全免费的开源插件为OBS Studio带来了数十种专业级特效&#xff0c;让普通用户也能轻松…

作者头像 李华
网站建设 2026/7/1 17:02:28

Vue轻量级后台管理系统基础模板:快速构建企业级应用

Vue轻量级后台管理系统基础模板&#xff1a;快速构建企业级应用 【免费下载链接】vue-admin-template Vue 轻量级后台管理系统基础模板 项目地址: https://gitcode.com/gh_mirrors/vue/vue-admin-template Vue轻量级后台管理系统基础模板是一款专为Vue.js开发者设计的高…

作者头像 李华
网站建设 2026/7/1 13:38:55

Roundcube Mail完整指南:构建高效个人Webmail系统的终极方案

Roundcube Mail完整指南&#xff1a;构建高效个人Webmail系统的终极方案 【免费下载链接】roundcubemail The Roundcube Webmail suite 项目地址: https://gitcode.com/gh_mirrors/ro/roundcubemail Roundcube Mail是一款功能强大的开源Webmail客户端&#xff0c;让你通…

作者头像 李华