编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • 数据结构与算法专栏
  • 基础认知

  • 线性结构

  • 树与哈希

  • 工业级实现

  • 算法思想

  • 实战与综合

  • 算法题考核

    • README
    • 数组算法题合集
    • 链表算法题合集
    • 栈队列算法题合集
    • 哈希算法题合集
    • 二叉树算法题合集
    • 堆算法题合集
    • 图算法题合集
    • 二分查找算法题合集
    • 双指针算法题合集
    • 排序算法题合集
    • 分治算法题合集
    • 贪心算法题合集
    • 回溯算法题合集
    • 动规算法题合集
    • 位运算算法题合集
      • 只出现一次的数字 I / II / III
        • 191 (136) 异或 a⊕a=0
        • 192 (137) 每个出现3次
        • 193 (260) 两个出现1次
      • O002 只出现一次的数字 II
        • 01. 题目
        • 02. 代码
      • O003 只出现一次的数字 III
        • 01. 题目
        • 02. 分析
        • 03. 代码
      • 位运算技巧集 (O004-O010)
        • 194 2的幂 (231)
        • 195 位1的个数 (191)
        • 196 颠倒二进制位 (190)
        • 197 数字范围按位与 (201)
        • 198 两整数之和 (371)
        • 199 汉明距离 (461)
        • 200 比特位计数 (338)
        • 位运算核心技巧
      • O005 位1的个数
        • 01. 题目
        • 02. 分析
        • 03. 代码
      • O006 颠倒二进制位
        • 01. 题目
        • 02. 代码
      • O007 数字范围按位与
        • 01. 题目
        • 02. 分析
      • O008 两整数之和
        • 01. 题目
        • 02. 分析
        • 03. 代码
      • O009 汉明距离
        • 01. 题目
        • 02. 代码
      • O010 比特位计数
        • 01. 题目
        • 02. 分析
        • 03. 代码
    • 数学算法题合集
  • 算法
  • 算法题考核
杨充
2018-02-19
目录

位运算算法题合集

# 只出现一次的数字 I / II / III

# 191 (136) 异或 a⊕a=0

public int singleNumber(int[] nums) { int r=0; for(int n:nums) r^=n; return r; }
1

Python: return reduce(xor, nums)

# 192 (137) 每个出现3次

public int singleNumber(int[] nums) { int o=0,t=0; for(int n:nums){ o=(o^n)&~t; t=(t^n)&~o; } return o; }
1

# 193 (260) 两个出现1次

public int[] singleNumber(int[] nums) { int x=0; for(int n:nums) x^=n; int m=x&-x,a=0; for(int n:nums) if((n&m)!=0) a^=n; return new int[]{a,x^a}; }
1

核心:xor & -xor 取最低位1,据此将数组分为两组。

复杂度:O(N)/O(1)。

# O002 只出现一次的数字 II

LeetCode 137 · ⭐⭐ · 位统计 / 状态机

# 01. 题目

[2,2,3,2] → 3。每个数字出现3次,唯一个出现1次。

# 02. 代码

public int singleNumber(int[] nums) {
    int ones=0, twos=0;
    for(int n:nums) {
        ones = (ones ^ n) & ~twos;
        twos = (twos ^ n) & ~ones;
    }
    return ones;
}
1
2
3
4
5
6
7
8

Python:

def singleNumber(self, nums):
    ones = twos = 0
    for n in nums:
        ones = (ones ^ n) & ~twos
        twos = (twos ^ n) & ~ones
    return ones
1
2
3
4
5
6

复杂度:O(N)/O(1)。

相关:O001 出现一次、O003 出现一次III

# O003 只出现一次的数字 III

LeetCode 260 · ⭐⭐ · 异或+分组

# 01. 题目

[1,2,1,3,2,5] → [3,5]。两个出现一次,其余两次。

# 02. 分析

全体异或 = a⊕b。取 mask = xor & -xor(最低位1)。根据 mask 将数组分为两组,每组各含一个目标数字。

# 03. 代码

public int[] singleNumber(int[] nums) {
    int xor=0; for(int n:nums) xor^=n;
    int mask=xor&-xor, a=0;
    for(int n:nums) if((n&mask)==0) a^=n;
    return new int[]{a, xor^a};
}
1
2
3
4
5
6

Python:

def singleNumber(self, nums):
    xor = reduce(xor, nums)
    mask = xor & -xor
    a = reduce(xor, (n for n in nums if n & mask))
    return [a, xor ^ a]
1
2
3
4
5

复杂度:O(N)/O(1)。

相关:O001 出现一次

# 位运算技巧集 (O004-O010)

# 194 2的幂 (231)

n>0 && (n&(n-1))==0 — 消最低位1后为0。

# 195 位1的个数 (191)

while(n!=0){ n&=n-1; cnt++; } — 每次消一个最低位1。

# 196 颠倒二进制位 (190)

public int reverseBits(int n) { int r=0; for(int i=0;i<32;i++){ r=(r<<1)|(n&1); n>>>=1; } return r; }
1

Python: int(bin(n)[2:].zfill(32)[::-1],2)

# 197 数字范围按位与 (201)

等价于找 m 和 n 的公共前缀。while(m<n){ m>>=1; n>>=1; s++; } return m<<s;

# 198 两整数之和 (371)

while(b!=0){ int c=(a&b)<<1; a^=b; b=c; } return a; — 异或=本位和,与运算<<1=进位。

# 199 汉明距离 (461)

Integer.bitCount(x^y) — 不同位=1。

# 200 比特位计数 (338)

dp[i]=dp[i>>1]+(i&1)

# 位运算核心技巧

操作 代码 用途
消最低位1 n&(n-1) 判2的幂、统计1
取最低位1 n&-n 分组
异或 a^b 去重、求和

# O005 位1的个数

LeetCode 191 · ⭐ · n & (n-1)

# 01. 题目

统计二进制中1的个数。11(1011) → 3。

# 02. 分析

n & (n-1) 消除最低位1。循环直到n=0。

# 03. 代码

Java:

public int hammingWeight(int n) { int c=0; while(n!=0){ n&=n-1; c++; } return c; }
1

Python:

def hammingWeight(self, n: int) -> int: return bin(n).count('1')
1

C++:

int hammingWeight(uint32_t n) { return __builtin_popcount(n); }
1

复杂度:O(k)/O(1),k为1的个数。

相关:O004 2的幂、O009 汉明距离

# O006 颠倒二进制位

LeetCode 190 · ⭐ · 逐位反转

# 01. 题目

颠倒32位无符号整数的二进制位。

# 02. 代码

Java:

public int reverseBits(int n) {
    int r=0; for(int i=0;i<32;i++){ r=(r<<1)|(n&1); n>>>=1; } return r;
}
1
2
3

Python:

def reverseBits(self, n: int) -> int:
    return int(bin(n)[2:].zfill(32)[::-1], 2)
1
2

C++:

uint32_t reverseBits(uint32_t n) {
    uint32_t r=0; for(int i=0;i<32;i++){ r=(r<<1)|(n&1); n>>=1; } return r;
}
1
2
3

复杂度:O(1)。

相关:O008 两整数之和

# O007 数字范围按位与

LeetCode 201 · ⭐⭐ · 公共前缀

# 01. 题目

[5,7] → 4。5(101) & 6(110) & 7(111) = 4(100)。

# 02. 分析

等价于找 m 和 n 的二进制公共前缀。

Java:

public int rangeBitwiseAnd(int m, int n) {
    int shift=0; while(m<n){ m>>=1; n>>=1; shift++; }
    return m<<shift;
}
1
2
3
4

Python:

def rangeBitwiseAnd(self, m: int, n: int) -> int:
    shift = 0
    while m < n: m >>= 1; n >>= 1; shift += 1
    return m << shift
1
2
3
4

复杂度:O(1)。

相关:O004 2的幂

# O008 两整数之和

LeetCode 371 · ⭐⭐ · 位运算模拟加法

# 01. 题目

不用 + - * / 计算两整数之和。

# 02. 分析

a^b = 本位和(无进位),(a&b)<<1 = 进位。循环直到进位为0。

# 03. 代码

Java:

public int getSum(int a, int b) { while(b!=0){ int c=(a&b)<<1; a^=b; b=c; } return a; }
1

Python:

def getSum(self, a: int, b: int) -> int:
    mask = 0xffffffff
    while b: a, b = (a^b)&mask, ((a&b)<<1)&mask
    return a if a <= 0x7fffffff else ~(a^mask)
1
2
3
4

C++:

int getSum(int a, int b) { while(b){ int c=(unsigned)(a&b)<<1; a^=b; b=c; } return a; }
1

复杂度:O(1)/O(1)。

相关:O009 汉明距离

# O009 汉明距离

LeetCode 461 · ⭐ · 异或+位计数

# 01. 题目

两个整数的汉明距离 = 二进制位不同的位置数。1(001) vs 4(100) → 2。

# 02. 代码

Java:Integer.bitCount(x ^ y) Python:bin(x ^ y).count('1') C++:__builtin_popcount(x ^ y)

复杂度:O(1)。

相关:O005 位1的个数

# O010 比特位计数

LeetCode 338 · ⭐ · DP+位运算

# 01. 题目

对 0≤i≤n 每个数,计算其二进制中1的个数。n=5 → [0,1,1,2,1,2]

# 02. 分析

$$dp[i] = dp[i >> 1] + (i & 1)$$

# 03. 代码

Java:

public int[] countBits(int n) {
    int[] dp=new int[n+1];
    for(int i=1;i<=n;i++) dp[i]=dp[i>>1]+(i&1);
    return dp;
}
1
2
3
4
5

Python:

def countBits(self, n):
    dp=[0]*(n+1)
    for i in range(1,n+1): dp[i]=dp[i>>1]+(i&1)
    return dp
1
2
3
4

复杂度:O(N)/O(N)。

相关:O005 位1的个数

#算法
上次更新: 2026/06/17, 12:46:05
动规算法题合集
数学算法题合集

← 动规算法题合集 数学算法题合集→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式