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

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

位运算在算法优化中极具价值,通过六个经典案例,演示如何利用异或消去、位图映射及进位模拟等技巧,高效解决字符唯一性判断、数字缺失查找及整数求和等问题。重点讲解如何以 O(1) 空间复杂度替代哈希表,提升代码性能并深化对底层二进制操作的理解。

筑梦师发布于 2026/3/22更新于 2026/5/55 浏览

前置知识储备

掌握基础位操作符是理解后续算法的前提。

经典题目实战

判定字符是否唯一

思路分析: 利用【位图】的思想,每一个【比特位】代表一个【字符】。一个 int 类型的变量有 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';
            // 先判断字符是否出现过
            if(((bitmap >> e) & 1) == 1) return false;
            // 把当前字符加入到位图中
            bitmap |= 1 << e;
        }
        return true;
    }
};

消失的数字

思路分析: 设数组大小为 n,原序列应为 [0, n],现缺失一个数。如果我们将数组中的所有数,以及 [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;
    }
};

两整数之和

思路分析: ● 异或 ^ 运算本质是【无进位加法】; ● 按位与 & 操作能够得到【进位】; ● 将无进位结果与进位左移后的结果相加,循环直到进位为 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;
    }
};

只出现一次的数字 II

思路分析: 数组中只有一个数出现一次,其余都出现三次。我们可以统计每一位上 1 出现的总次数。对于目标数 ret 的某一位,如果该位在数组所有数的对应位上总和模 3 余 1,则说明 ret 的这一位是 1,否则为 0。通过遍历 32 位即可还原出 ret。

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

思路分析:

  1. 将所有数异或在一起,结果为两个只出现一次的数 a 和 b 的异或值 tmp = a ^ b。
  2. a 不等于 b,所以 tmp 至少有一位为 1。找到这一位,它代表了 a 和 b 在该位上的二进制不同。
  3. 根据这一位将数组分为两类,分别异或,即可得到 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((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;
        
        // 找出 a, b 中比特位不同的那一位
        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. 经典题目实战
  3. 判定字符是否唯一
  4. 消失的数字
  5. 两整数之和
  6. 只出现一次的数字 II
  7. 只出现一次的数字 III
  8. 消失的两个数字
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • llama-cpp-python 完整安装与配置指南
  • Python 爬虫实战:抓取今日头条热榜 TOP50 数据
  • Jupyter Notebook 安装与配置完整指南
  • 基于低代码平台的工单管理系统解决方案
  • MySQL 8.0 Windows 安装配置教程
  • MixAIHub:主流 AI 模型聚合访问平台
  • Spring AI 多轮对话与记忆机制实战:构建高可用智能客服
  • OpenClaw 与主流 AI 编程工具的本质差异解析
  • LLaMA-Factory 微调 Qwen-0.6B 模型高通 NPU 部署指南
  • LLaMA-Factory 大模型微调实战:Qwen3 + LoRA
  • Microsoft Edge WebView2 Runtime 快速部署与调试指南
  • OpenClaw Web 管理面板配置与大模型集成实践
  • GLM-4-9B开源大模型:超越Llama-3-8B的性能评测
  • Web 扫雷游戏项目实现与说明
  • 1Panel 部署 Open WebUI:ghcr.io 镜像加速与无缝切换方案
  • 本地部署开源大语言模型框架 Ollama 入门指南
  • Webots 2025a + ROS 2 Jazzy e-puck 机器人仿真与导航教程
  • Unreal Engine 4.27 搭建 AirSim 无人机仿真环境:澳大利亚农村场景
  • Qwen3-VL WebUI 部署稳定性测试:72 小时压测实录
  • 前端多版本零 404 部署实践:根因分析与落地方案

相关免费在线工具

  • 加密/解密文本

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