神奇的位运算——力扣136.只出现一次的数字

力扣136.只出现一次的数字


【LeetCode题解】只出现一次的数字------Set解法和神奇的位运算

一、题目描述

给你一个 非空整数数组 nums ,其中除了某个元素只出现一次以外,其余每个元素均出现两次。

请你找出那个只出现了一次的元素。

要求:

  • 时间复杂度为 O(n)
  • 空间复杂度为 O(1)

示例:

复制代码
输入:nums = [2,2,1]
输出:1

输入:nums = [4,1,2,1,2]
输出:4

输入:nums = [1]
输出:1

二、思路分析

这道题一看就让人想到用哈希结构来记录出现次数,但题目明确要求常量额外空间,所以我们要换个角度思考。

常见思路有两个:

  1. HashSet:存进去、出现两次就移除,最后剩下的就是答案。
  2. 位运算(异或 XOR):充分利用数学性质,优雅解决问题。

三、解法一:HashSet(直观思路)

我们先说最容易想到的办法。

  • 遍历数组,把数字加入 Set。
  • 如果已经存在,就移除它。
  • 遍历结束后,Set 里只会留下那个只出现一次的数。

代码

java 复制代码
import java.util.HashSet;

class Solution {
    public int singleNumber(int[] nums) {
        HashSet<Integer> set = new HashSet<>();
        for (int num : nums) {
            if (!set.add(num)) {
                set.remove(num);
            }
        }
        return set.iterator().next();
    }
}

复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

虽然简单直观,但没有满足题目的空间要求。


四、解法二:位运算(异或 XOR)

这才是本题的核心与精华。

异或运算的性质

  1. a ^ a = 0
  2. a ^ 0 = a
  3. 交换律、结合律

结合这三个性质,可以看出:

  • 两个相同的数会互相抵消变成 0
  • 所有数异或一遍,剩下的就是只出现一次的那个数

举例

复制代码
nums = [4,1,2,1,2]

4 ^ 1 ^ 2 ^ 1 ^ 2
= (1 ^ 1) ^ (2 ^ 2) ^ 4
= 0 ^ 0 ^ 4
= 4

代码

java 复制代码
class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for (int num : nums) {
            ans ^= num;
        }
        return ans;
    }
}

复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
    这是题目的最优解。

五、方法对比

方法 时间复杂度 空间复杂度 思路
HashSet O(n) O(n) 简单直观,适合入门
XOR位运算 O(n) O(1) 优雅高效,面试必杀

六、进阶拓展

如果你觉得本题太简单,可以思考以下变种:

  1. 每个数字出现三次,只有一个数字出现一次

    • 可以用位运算统计每一位上 1 出现的次数,对 3 取模即可得到答案。
  2. 有两个数字各出现一次,其他数字出现两次

    • 先整体异或得到 x ^ y,再找出一个不为 0 的二进制位,将数组划分为两组,分别异或即可得到 xy

这些变种同样考验对位运算的理解,适合进一步练习。


七、总结

  • 如果不考虑空间复杂度,Set 是最容易想到的方案。
  • 如果追求最佳解,位运算 XOR 是唯一王道
  • 理解 XOR 的数学本质,可以帮助你秒杀一类经典问题。

相关推荐
SimonKing2 小时前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员
FastBean2 小时前
Jackson View Extension Spring Boot Starter
java·后端
Seven973 小时前
剑指offer-79、最⻓不含重复字符的⼦字符串
java
皮皮林55112 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河13 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
地平线开发者13 小时前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮14 小时前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者14 小时前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考14 小时前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习