LeetCode 137. 只出现一次的数字 II —— 位运算解法

题目描述

给你一个整数数组 nums ,除某个元素仅出现一次外,其余每个元素都恰出现三次。请你找出并返回那个只出现一次的元素。

你必须设计并实现 线性时间复杂度 且使用 常数级空间 的算法。

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 3 * 10^4

  • -2^31 <= numsi <= 2^31 - 1

  • 除某个元素仅出现一次外,其余每个元素都恰出现三次


解题思路

这道题是 位运算经典题 ,可以用 按位统计 的方法解决。

方法 1:按位统计(简单易理解)

  1. 统计每一位 1 的个数

    • int 有 32 位

    • 建一个 bit[32] 数组,表示每一位上 1 出现的次数

  2. 对 3 取模

    • 出现 3 次的数字在每一位上的 1 的个数是 3 的倍数

    • 只出现一次的数字会留下余数 1

  3. 还原结果

    • 将每一位余数为 1 的位置拼接起来,即为只出现一次的数字

C 语言实现

复制代码
int singleNumber(int* nums, int numsSize) {
    int bit[32] = {0};
    
    // 统计每一位1的个数
    for (int i = 0; i < numsSize; i++) {
        for (int j = 0; j < 32; j++) {
            bit[j] += (nums[i] >> j) & 1;
        }
    }

    int result = 0;

    // 取模3并还原结果
    for (int j = 0; j < 32; j++) {
        if (bit[j] % 3) {
            result |= (1u << j);   // 注意用 unsigned 避免符号位报错
        }
    }

    return result;
}

⚠️ 注意:

  • 1 << 31 可能会出现 未定义行为,因为 1 是 signed int

  • 用 1u << j 可以安全操作符号位


方法 2:状态机位运算(更优雅)

这个方法用 两个变量 ones 和 twos 表示每一位出现次数的状态:

  • ones:该位出现过 1 次

  • twos:该位出现过 2 次

  • 当某位出现 3 次时,自动归零

核心公式:

复制代码
ones = (ones ^ num) & ~twos;
twos = (twos ^ num) & ~ones;

最终 ones 就是只出现一次的数字。

代码示例:

复制代码
int singleNumber(int* nums, int numsSize) {
    int ones = 0, twos = 0;
    for (int i = 0; i < numsSize; i++) {
        ones = (ones ^ nums[i]) & ~twos;
        twos = (twos ^ nums[i]) & ~ones;
    }
    return ones;
}
  • 时间复杂度:O(n)

  • 空间复杂度:O(1)


总结

  • 本题核心是 位运算 + 计数取模

  • 方法 1 用 32 位数组,易理解,但空间稍大

  • 方法 2 用 状态机位运算,常数空间,面试更加加分

  • 注意 符号位左移 的写法,要用 unsigned int 避免运行错误


💡 拓展思路:

  • 如果数字出现次数不是 3,而是其他 k,按位统计仍然适用

  • 方法 2 的状态机也可以扩展到 k 次出现的情况

相关推荐
jyyyx的算法博客2 分钟前
传球游戏【思维】
算法
FL162386312910 分钟前
关于2026年南昌大学811信号与系统最后一题电路系统解题思路
算法
殷色玫瑰11 分钟前
C++ STL:map 与 set 详解——从底层红黑树到实际应用
c语言·数据结构·c++·算法·visualstudio·rpc
行者全栈架构师17 分钟前
【鸿蒙心迹】鸿蒙网络请求架构实战——@ohos.net.http 到 Axios 封装、拦截器与统一错误处理(HarmonyOS 7.x)
前端·算法·架构
小宋102131 分钟前
OpenTelemetry GenAI可观测性实战:串起模型、工具、Token与错误
java·人工智能·算法·贪心算法
嫂子开门我是_我哥33 分钟前
青少年抑郁、焦虑、失眠与自杀相关表现的症状联系:一篇网络分析论文所使用的算法深度解读
论文阅读·算法·论文笔记
字节跳动的猫41 分钟前
LikeShop 商品评价体系二开:追评、晒图审核与评价标签筛选功能开发
运维·数据结构·数据库
渊鱼L44 分钟前
CAD随机颗粒插件2D V2.0 更新说明
算法
Lazionr1 小时前
unordered_map和unordered_set的使用
开发语言·c++·算法
行者全栈架构师1 小时前
从 55% 到 6%:一个快餐营养规划器的算法迭代实录
后端·算法·架构