当前位置: 首页 > news >正文

二进制枚举算法

二进制枚举算法详解

一、什么是二进制枚举算法

二进制枚举算法是一种 通过整数的二进制表示来枚举所有子集 的方法。适用于处理组合问题,特别是与“取或不取”某个元素相关的场景。

📌 原理说明

设有一个集合 A = [a₀, a₁, ..., aₙ₋₁],我们要枚举它的所有子集。集合中每个元素有两种状态:选 or 不选。因此总共有 2ⁿ 种子集。

我们可以用一个 n 位的 二进制数 来表示一个子集,例如:

二进制位子集含义
0不选该元素
1选该元素

比如对于集合 [1, 2, 3]

  • 000 → 空集 {}
  • 101 → 选第1和第3个元素 → {1, 3}
  • 111 → 全选 → {1, 2, 3}

✅ 实现步骤

  1. 确定元素个数:假设为 n
  2. 循环从 02ⁿ - 1,每个数的二进制表示对应一个子集
  3. 用位运算判断每一位是否为 1
  4. 构造当前子集
  5. 输出或处理这个子集

二、图示理解

假设集合为 [a, b, c],其子集枚举如下(每一行是一个整数的二进制表示):

css复制编辑i(二进制)  是否选a  是否选b  是否选c   子集
000           0        0        0       {}
001           0        0        1       {c}
010           0        1        0       {b}
011           0        1        1       {b, c}
100           1        0        0       {a}
101           1        0        1       {a, c}
110           1        1        0       {a, b}
111           1        1        1       {a, b, c}

三、代码实现(Go 示例)

✅ Go 实现:

go复制编辑package mainimport "fmt"func binaryEnum(arr []int) {n := len(arr)for i := 0; i < (1 << n); i++ {var subset []intfor j := 0; j < n; j++ {if (i>>j)&1 == 1 {subset = append(subset, arr[j])}}fmt.Println(subset)}
}func main() {arr := []int{1, 2, 3}binaryEnum(arr)
}

四、二进制枚举的优势

优势说明
✅ 简洁使用整数和位运算代替递归或多重循环
✅ 效率高位运算在底层执行非常快
✅ 结构清晰子集状态一一对应二进制
✅ 易扩展可结合子集统计、位掩码优化

五、适用场景

小规模子集枚举问题

当元素个数不大(通常 n ≤ 20),可暴力枚举 2ⁿ 种组合。

集合操作(求交并差)

集合可用一个二进制数表示,如 set = 0b10101 表示选了第1、第3、第5个元素。

状态压缩动态规划(Bitmask DP)

如 TSP(旅行商问题)、集合覆盖、最短Hamilton路径等问题。

穷举判断满足某种条件的子集

如:求所有子集中和为某个目标值的个数。


六、进阶优化技巧

  • 提前剪枝:遇到明显不符合要求的中间状态时立即跳过
  • 记录中间状态:用 map 缓存某些子集结果
  • 结合排列枚举:在每个子集内部再对元素进行排列

七、常见误区

误区正确做法
n 很大时也使用二进制枚举超过 n = 25 后就非常慢,应换动态规划或回溯
忘记位移方向(i >> j) 是向右移第 j
忽视索引越界注意 arr[j] 不要超过范围
忽略子集顺序二进制枚举默认顺序由低到高

八、小练习建议

  1. 给定整数数组,输出所有子集
  2. 求所有子集中元素和为 target 的子集个数
  3. 二进制枚举所有满足异或为 0 的子集
  4. 用二进制枚举解决集合划分问题(如背包)

相关文章:

  • 嵌入式学习——虚拟机通信
  • 零基础上手Python数据分析 (19):Matplotlib 高级图表定制 - 精雕细琢,让你的图表脱颖而出!
  • xss4之cookie操作
  • 前端知识深度学习
  • 认识MCP Function Calling AI Agent
  • 每日一题算法——链表相交
  • 21.Chromium指纹浏览器开发教程之触摸屏点指纹定制
  • Web前端:百度首页克隆 - 前端开发练习
  • 深入浅出 C++ 核心基础:从语法特性到入门体系构建
  • langchain-nextjs-template 模板安装与配置
  • 【深度学习—李宏毅教程笔记】各式各样的 Attention
  • jupyter切换存储路径
  • C++入门基础:引用,auto自动关键字,内联函数,范围for循环
  • 【C++】 —— 笔试刷题day_22
  • Postgresql几个常用的json操作
  • 安卓手机怎样配置数据加速
  • 10 C 语言常量详解:#define 与 const 定义常量及其区别与应用
  • JavaScript 版本号比较
  • 软件设计师/系统架构师---计算机网络
  • C++:在条件判断时何时为if,何时为else (易混淆※※※)
  • 海南陵水一酒店保洁员调包住客港币,被判刑一年六个月
  • 我国将组织实施梦舟飞船零高度逃逸、揽月着陆器综合着陆起飞验证等试验
  • 用8年还原曹操墓鉴定过程,探寻曹操墓新书创作分享会举行
  • 美菲开始举行年度军演,外交部:菲公然站在地区国家的对立面
  • IPO周报|本周暂无新股申购,上周上市新股中签浮盈均超1.6万
  • 东北三省,十年少了一个“哈尔滨”