news 2026/5/1 9:13:27

力扣136.只出现一次的数字-异或和HashMap

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
力扣136.只出现一次的数字-异或和HashMap

问题描述

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

方法一:传统HashMap解法

思路分析

最直观的想法是:统计每个数字出现的次数,然后找出只出现一次的那个数字。

实现代码

class Solution { public int singleNumber(int[] nums) { // 创建HashMap来存储数字及其出现次数 Map<Integer, Integer> map = new HashMap<>(); // 遍历数组,统计每个数字出现的次数 for (int num : nums) { // 如果map中已经包含这个数字 if (map.containsKey(num)) { // 出现次数加1 map.put(num, map.get(num) + 1); } else { // 第一次出现,设为1 map.put(num, 1); } } // 遍历map,找到出现次数为1的数字 for (Integer key : map.keySet()) { if (map.get(key) == 1) { return key; } } // 理论上不会执行到这里(题目保证有解) return -1; } }

复杂度分析

  • 时间复杂度:O(n),需要遍历数组一次,遍历map一次

  • 空间复杂度:O(n),最坏情况下需要存储n/2+1个键值对

优缺点

  • ✅ 思路直观,容易理解

  • ✅ 适用于更一般的情况(如找出出现奇数次/偶数次的数字)

  • ❌ 需要额外的存储空间

  • ❌ 代码相对冗长

方法二:HashMap改进版

思路分析

Java 8引入了一些新的API,可以让我们的代码更加简洁优雅。

实现代码

class Solution { public int singleNumber(int[] nums) { Map<Integer, Integer> map = new HashMap<>(); // 使用getOrDefault简化代码 for (int num : nums) { // 如果num存在,获取当前值加1;如果不存在,用0加1 map.put(num, map.getOrDefault(num, 0) + 1); } // 使用entrySet同时获取key和value,避免多次查找 for (Map.Entry<Integer, Integer> entry : map.entrySet()) { if (entry.getValue() == 1) { return entry.getKey(); } } return -1; } }

关键技术点

1. getOrDefault方法

getOrDefault方法在key存在时返回对应的value,不存在时返回指定的默认值(这里是0)。

2. entrySet遍历
// 使用entrySet(只需一次遍历) for (Map.Entry<Integer, Integer> entry : map.entrySet()) { if (entry.getValue() == 1) { // 直接获取value return entry.getKey(); // 直接获取key } }

优缺点

  • ✅ 代码更简洁

  • ✅ 使用entrySet提升遍历效率

  • ❌ 仍然需要额外的存储空间

方法三:异或运算的魔法

思路分析

这是一个需要点数学思维的解法,利用了异或运算的几个重要性质:

  1. 任何数和0异或等于它本身:a ⊕ 0 = a

  2. 任何数和自身异或等于0:a ⊕ a = 0

  3. 异或运算满足交换律和结合律:a ⊕ b ⊕ a = (a ⊕ a) ⊕ b = 0 ⊕ b = b

实现代码

class Solution { public int singleNumber(int[] nums) { int result = 0; for (int num : nums) { result ^= num; // 对每个数字进行异或运算 } return result; } }

复杂度分析

  • 时间复杂度:O(n),只需遍历一次数组

  • 空间复杂度:O(1),只使用常数级别的额外空间

优缺点

  • ✅ 时间复杂度最低

  • ✅ 空间复杂度最优

  • ✅ 代码极其简洁

  • ❌ 需要理解异或运算的特性

  • ❌ 仅适用于特定情况(其他数字都出现两次)

三种方法对比

特性传统HashMap改进HashMap异或运算
时间复杂度O(n)O(n)O(n)
空间复杂度O(n)O(n)O(1)
代码简洁度一般简洁极简
通用性高(可处理任意次数)高(可处理任意次数)低(只适用于两次)
思维难度

拓展思考

如果其他数字出现三次,只有一个出现一次?

这时候异或运算就不适用了,但可以使用HashMap或位运算的扩展解法。

如果有两个只出现一次的数字?

这需要更巧妙的位运算技巧,可以通过分组异或来解决。

总结

这道题目看似简单,却蕴含了丰富的算法思想:

  1. HashMap解法:体现了最直接的"计数"思维,是解决频率统计问题的通用方法

  2. API优化:展示了如何利用语言特性写出更优雅、高效的代码

  3. 异或解法:揭示了数学思维在算法中的强大威力

在实际开发中,我们通常选择HashMap解法,因为它通用且易于理解和维护。但在面试或竞赛中,异或解法往往更受青睐,因为它展示了候选人对问题的深入理解。


希望这篇文章能帮助你更好地理解不同的解题思路。记住,没有最好的算法,只有最适合场景的算法。

思考题:如果题目改为"除了一个数字出现一次外,其他数字都出现三次",你能想到几种解法?

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

AI短剧智能创作平台核心源码,剧本、分镜、视频生成一体化

温馨提示&#xff1a;文末有资源获取方式影视制作的神秘面纱正在被AI技术掀开。当AI短剧以数亿播放量证明其市场吸引力时&#xff0c;一套能够整合前沿技术、提供完整解决方案的创作系统&#xff0c;就成为内容创作者的“数字影棚”。源码获取方式在源码闪购网。系统核心功能列…

作者头像 李华
网站建设 2026/4/27 19:03:43

单北斗GNSS变形监测系统是什么?主要有怎样的应用与优势?

单北斗GNSS变形监测系统是一种通过北斗卫星技术实现精确监测的高效方案。该系统主要用于实时监测地表的形变现象&#xff0c;广泛应用于地质灾害预警、基础设施安全检查等领域。其核心特点在于高精度传感器的应用&#xff0c;能够以毫米级的精准度捕捉地表变化信息。此系统不仅…

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

防酒驾(有完整资料)

资料查找方式&#xff1a;特纳斯电子&#xff08;电子校园网&#xff09;&#xff1a;搜索下面编号即可编号&#xff1a;CP-51-2021-020设计简介&#xff1a;本设计是基于单片机的防酒驾系统&#xff0c;主要实现以下功能&#xff1a;可通过LCD1602显示车内酒精浓度&#xff1b…

作者头像 李华
网站建设 2026/4/4 8:59:18

AI短剧创富新风口,零门槛智能创作源码系统,带完整的搭建部署教程

温馨提示&#xff1a;文末有资源获取方式在AI视频模型技术飞速进步的当下&#xff0c;短剧创作领域正经历一场颠覆性变革。传统影视制作的高壁垒被彻底打破&#xff0c;全民创作与创富的时代大门已然开启。数据显示&#xff0c;仅2025年下半年&#xff0c;播放量破千万的AI短剧…

作者头像 李华
网站建设 2026/4/30 21:34:29

计算机毕业设计|基于springboot + vue个人记账系统(源码+数据库+文档)

个人记账 目录 基于springboot vue个人记账系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue个人记账系统 一、前言 博主介绍&#xff1a;✌️大…

作者头像 李华