跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

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

综述由AI生成位运算在算法优化中常能起到奇效,特别是在空间受限或需要快速判重的场景。本文通过六个经典例题,展示了如何利用位图、异或消去特性、进位模拟及位统计等技巧解决实际问题。从判定字符唯一性到寻找缺失数字,再到处理多次出现的数字,核心在于理解二进制层面的运算规律,从而将时间或空间复杂度降至最优。掌握这些位操作思维,能让代码更简洁高效。

黑客发布于 2026/3/15更新于 2026/5/25 浏览

前置知识

在进行位运算优化前,建议先熟悉基本的位操作符(与、或、异或、移位等)。它们不仅是底层逻辑的基础,更是解决特定算法问题的利器。

经典例题解析

判定字符是否唯一

这道题如果用哈希表,空间复杂度是 O(N)。利用位图思想,我们可以把空间压缩到 O(1)。一个 32 位整数足以覆盖所有小写字母。每一位代表一个字符,0 表示未出现,1 表示已出现。

class Solution {
public:
    bool isUnique(string astr) {
        // 利用鸽巢原理优化,超过 26 个字符必然有重复
        if(astr.size() > 26) return false;
        int bitmap = 0;
        for(auto i : astr){
            int e = i - 'a';
            // 检查该位是否已被置为 1
            if(((bitmap >> e) & 1) == 1) return false;
            // 将当前字符对应的位置 1
            bitmap |= (1 << e);
        }
        return true;
    }
};

消失的数字

数组包含 [0, n] 中缺失的一个数。核心在于异或的'消消乐'特性:相同数字异或为 0。将数组元素与完整序列 [0, n] 全部异或,成对的数字抵消,剩下的就是缺失值。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int ret = 0;
        // 先异或数组中的所有数
        for( i : nums) ret ^= i;
        
        ( i = ; i <= nums.(); i++) ret ^= i;
         ret;
    }
};
auto
// 再异或 0 到 n 的所有数
for
int
0
size
return

两整数之和

硬件层面加法器通常由半加器和全加器组成。异或 ^ 相当于无进位加法,按位与 & 左移一位 <<1 得到进位。循环直到进位为 0,即可得到最终和。注意处理负数时的符号位问题,使用 unsigned int 辅助计算进位更安全。

class Solution {
public:
    int getSum(int a, int b) {
        while(b){
            int x = a ^ b; // 无进位相加的结果
            // 排除 -1 的情况,使用 unsigned int 防止右移符号位扩展问题
            unsigned int carry = (unsigned int)(a & b) << 1;
            a = x;
            b = carry;
        }
        return a;
    }
};

只出现一次的数字 II

除了目标数外,其他数都出现三次。统计每一位上 1 出现的总次数,对 3 取模。如果余数为 1,说明目标数在该位上是 1;否则为 0。通过遍历 32 位,即可还原目标数。

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;
    }
};

只出现一次的数字 III

有两个数只出现一次,其余两次。先全部异或得到 a ^ b。因为 a != b,结果中至少有一位是 1。找到这一位,根据该位是 0 还是 1 将数组分为两组,分别异或,即可分离出 a 和 b。

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int tmp = 0;
        for(auto x : nums) tmp ^= x;
        
        // 找出 a, b 中比特位不同的那一位
        int diff = 0;
        while(1){
            if(((tmp >> diff) & 1) == 1) break;
            else diff++;
        }
        
        // 根据 diff 位的不同,将所有数划分成两类
        int a = 0, b = 0;
        for(auto x : nums){
            if((1 & (x >> diff)) == 1) b ^= x;
            else a ^= x;
        }
        return {a, b};
    }
};

消失的两个数字

这是'消失的数字'与'只出现一次的数字 III'的组合。先将数组元素与 [1, n+2] 区间内的所有数异或,问题转化为寻找两个只出现一次的数。后续步骤同上一题,只需记得在分组异或时也要把区间内的数字参与运算。

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((1 & (x >> diff)) == 1) b ^= x;
            else a ^= x;
        }
        for(int i = 1; i <= nums.size() + 2; i++){
            if((1 & (i >> diff)) == 1) b ^= i;
            else a ^= i;
        }
        return {a, b};
    }
};

目录

  1. 前置知识
  2. 经典例题解析
  3. 判定字符是否唯一
  4. 消失的数字
  5. 两整数之和
  6. 只出现一次的数字 II
  7. 只出现一次的数字 III
  8. 消失的两个数字
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • ToDesk、顺网云、青椒云三款云电脑 AIGC 性能实测对比
  • MCP Server 实现 Excel 表格一键生成可视化图表 HTML 报告
  • Qclaw 微信 AI 智能体使用教程
  • C++ 笔试算法实战:打怪模拟、字符串分类与连通分量
  • C++ 多态深度解析:从虚函数表到底层机制
  • Java 零基础入门教程:环境搭建、核心语法与实战
  • Pico 无线串流 SteamVR 安装与网络环境配置指南
  • TS2320 错误的本质、触发场景与在 Angular / RxJS 项目中的系统化应对
  • SkyWalking .NET / C++ / Lua 探针现状与社区支持
  • 论文 AI 率多少算正常?各高校 AIGC 检测标准汇总
  • OpenClaw 安装部署全流程 - 搭建自托管 AI 助手
  • 基于魔搭与 LLaMA Factory 的大模型微调全流程实操
  • 前端代码分割与懒加载实践
  • 前端响应式进阶:从 vw/vh 到 clamp() 的实战思考
  • AI Agent Skills 资源合集:支持 Cursor、Claude Code 与 Copilot 的一键部署方案
  • DeepFace 与 OpenCV 实现情绪分析器
  • 基于 AI 提示词的电商产品详情页高效撰写指南
  • OpenClaw 全平台安装与 Telegram/飞书集成部署指南
  • 机器人算法十年演进:从规则驱动到具身认知
  • C++11 手写 Promise 实现及与 std::promise 对比

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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