跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

算法优选:位运算实战技巧

位运算利用二进制特性优化空间与时间复杂度。通过位图解决字符唯一性,异或消除重复项查找缺失数字,模拟加法器实现整数求和,统计比特位模三定位单一元素,以及分组异或分离两个目标数。掌握这些技巧可显著提升算法效率。

人间过客发布于 2026/3/28更新于 2026/10/22106 浏览

位运算在算法中的经典应用

1. 前置知识

熟练掌握位操作符(如 &, |, ^, ~, <<, >>)是理解以下算法的基础。建议先回顾位运算的基本逻辑与优先级。

2. 经典例题解析

2.1 判定字符是否唯一

核心思路: 利用【位图】思想,用一个整数的 32 个比特位代表字符集合。对于小写字母,仅需 26 位即可覆盖。若某位为 0 表示未出现,为 1 表示已出现。这相当于用整数充当哈希表。

注意利用鸽巢原理:若字符串长度超过 26,必然有重复字符,可直接返回 false。

class Solution {
public:
    bool isUnique(string astr) {
        // 利用鸽巢原理优化
        if(astr.size() > 26) return false;
        
        int bitmap = 0;
        for(auto i : astr){
            int e = i - 'a';
            // 先判断字符是否出现过
            if(((bitmap >> e) & 1) == 1) return false;
            // 把当前字符加入到位图中
            bitmap |= (1 << e);
        }
        return true;
    }
};

2.2 消失的数字

核心思路: 数组大小为 n,包含 [0, n] 中缺失的一个数。利用异或运算的自反性($a \oplus a = 0$),将数组所有元素与 [0, n] 的所有数字进行异或,成对的数字会相互抵消,最终结果即为缺失的数字。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int ret = 0;
        // 异或数组中的所有元素
        for(auto i : nums) ret ^= i;
        // 异或 [0, n] 范围内的所有数字
        for(int i = 0; i <= nums.size(); i++) ret ^= i;
        return ret;
    }
};

2.3 两整数之和

核心思路: 计算机底层加法由两部分组成:无进位和与进位。

  • 异或 ^ 得到无进位加法结果。
  • 按位与 & 左移一位 << 1 得到进位值。 循环执行直到进位为 0。
class Solution {
public:
    int getSum(int a, int b) {
        while(b){
            int x = a ^ b;          // 无进位相加的结果
            unsigned int carry = (unsigned int)(a & b) << 1; // 进位
            a = x;
            b = carry;
        }
        return a;
    }
};

2.4 只出现一次的数字 II

核心思路: 数组中除一个元素外,其余都出现三次。我们需要统计每一位上 1 出现的总次数。如果某一位的 1 的总数能被 3 整除,说明目标数该位为 0;否则为 1。

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret = 0;
        for(int i = 0; i < 32; i++){
            int sum = 0;
            for(auto x : nums)
                if(x & (1 << i)) sum++;
            sum %= 3;
            if(sum & 1) ret |= (1 << i);
        }
        return ret;
    }
};

2.5 只出现一次的数字 III

核心思路:

  1. 全部异或得到 $a \oplus b$(假设两个单独数为 a, b)。
  2. 找到 $a \oplus b$ 中任意一个为 1 的位(即 a, b 不同的位)。
  3. 根据该位将数组分为两组,分别异或,即可还原 a 和 b。
class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int tmp = 0;
        for(auto x : nums) tmp ^= x;
        
        int diff = 0;
        while(1){
            if(((tmp >> diff) & 1) == 1) break;
            else diff++;
        }
        
        int a = 0, b = 0;
        for(auto x : nums){
            if((x >> diff) & 1) b ^= x;
            else a ^= x;
        }
        return {a, b};
    }
};

2.6 消失的两个数字

核心思路: 本题结合了'消失的数字'与'只出现一次的数字 III'。 先将数组元素与 [1, n+2] 区间所有数异或,问题转化为寻找两个只出现一次的数。后续步骤同 2.5,只需额外对区间内的数字也进行分组异或处理。

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) {
        int tmp = 0;
        for(auto x : nums) tmp ^= x;
        for(int i = 1; i <= nums.size() + 2; i++) tmp ^= i;
        
        int diff = 0;
        while(1){
            if(((tmp >> diff) & 1) == 1) break;
            else diff++;
        }
        
        int a = 0, b = 0;
        for(auto x : nums){
            if((x >> diff) & 1) b ^= x;
            else a ^= x;
        }
        for(int i = 1; i <= nums.size() + 2; i++){
            if((i >> diff) & 1) b ^= i;
            else a ^= i;
        }
        return {a, b};
    }
};

目录

  1. 位运算在算法中的经典应用
  2. 1. 前置知识
  3. 2. 经典例题解析
  4. 2.1 判定字符是否唯一
  5. 2.2 消失的数字
  6. 2.3 两整数之和
  7. 2.4 只出现一次的数字 II
  8. 2.5 只出现一次的数字 III
  9. 2.6 消失的两个数字

更多推荐文章

查看全部
  • 大模型基座训练的挑战与难点
  • Python 中 as 关键字的作用与用法
  • AI 时代创作者的核心身份与生存法则
  • 自然语言处理在金融领域的应用与实战
  • C++ unordered_map 与 unordered_set 核心原理及模拟实现
  • 网络安全挖洞实战指南:工具准备与漏洞提交流程
  • C++ STL 标准库算法详解与实战
  • 秋田中文离线地图 App 上线
  • 构建离线私有 GPT:实现本地大模型与文档问答
  • Python+Agent 入门实战:从零搭建 AI 智能体
  • 重读《人人都是产品经理》:AI 时代的经典内核与产品实践
  • LLM Prompt 万能框架:多层次架构解析与实践
  • Ubuntu 下安装与配置 AMULE 客户端
  • 大模型后训练技术全解析:Llama3.1、DeepSeek-V3 等关键实践
  • C++反向迭代器实现、逆波兰表达式与计算器实现
  • OpenAI 集成 LangChain 实战使用详解
  • 大模型在影视动漫行业的应用案例详解
  • 利用文心一言为智能体设计稳定的工作流提示词
  • 基于 Spring Boot 的流浪动物救助与管理系统的设计与实现
  • 2026 Web 开发趋势:性能即默认,少写代码多思考

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online