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

算法:位运算技巧与经典题目解析

位运算利用二进制特性优化算法效率。通过位图思想判断字符唯一性;利用异或运算抵消重复元素寻找缺失数字;结合无进位加法与进位逻辑实现整数求和;针对出现次数不同的数字,通过统计比特位总和或分组异或还原目标值。涵盖唯一字符、消失数字、两数之和及单数字变体等经典问题。

花里胡哨发布于 2026/3/26更新于 2026/6/1432 浏览

前置知识

文章配图

经典题目解析

判定字符是否唯一

算法思路:

利用【位图】的思想,每一个【比特位】代表一个【字符】,一个 int 类型的变量的 32 位足够表示所有的小写字母。比特位里若为 0,表示这个字符没有出现过;若为 1,表示该字符出现过。 可以用一个【整数】来充当【哈希表】。

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

消失的数字

算法思路:

设数组的大小为 n,则之前的数组就是 [0, n],数组中是 [0, n] 中缺失一个数形成的序列。若,我们把数组中的所有数,以及 [0, n] 中的所有数全部【异或】在一起,那么根据【异或】运算的【抵消规则】,最终的异或结果就是缺失的数字。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int ret = 0;
        for (auto i : nums) ret ^= i;
        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; // 无进位相加的结果
            // 排除 -1 的情况
            unsigned int carry = (unsigned int)(a & b) << 1; // 进位
            a = x;
            b = carry;
        }
        return a;
    }
};

只出现一次的数字 II

算法思路:

设要找的数为 ret。由于整个数组中,需要找的元素只出现了【一次】,其余的数都出现了【三次】,因此我们可以根据所有数的【某一个比特位】的总和 % 3 的结果,快速定位到 ret 的【一个比特位】上的值是 0 还是 1。 这样,我们通过 ret 的每一位比特位上的值,就可以将 ret 给还原出来。

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret = 0;
        for (int i = 0; i < 32; i++) { // 依次修改 ret 中的每一位
            int sum = 0;
            for (auto x : nums) // 计算 nums 中所有第 i 位的和
                if (x & (1 << i)) sum++;
            sum %= 3;
            if (sum & 1) ret |= 1 << i;
        }
        return ret;
    }
};

只出现一次的数字 III

算法思路:

  1. 将所有数异或在一起,由于只有两个数出现一次,其余都出现两次。所以最后的结果为 a^b。
  2. a 和 b 不相等,因此 a 和 b 的二进制一定有至少一位不相同。
class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        // 1. 将所有的数异或在一起
        int tmp = 0;
        for (auto x : nums) tmp ^= x;
        
        // 2. 找出 a,b 中比特位不同的那一位
        int diff = 0;
        while (true) {
            if (((tmp >> diff) & 1) == 1) break;
            else diff++;
        }
        
        // 3. 根据 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] 区间内的所有数【异或】在一起,问题就变成了:有两个数出现了【一次】,其余所有的数出现了【两次】。进而变成了【只出现一次的数字 III】这道题。

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) {
        // 1. 将所有的数异或在一起
        int tmp = 0;
        for (auto x : nums) tmp ^= x;
        for (int i = 1; i <= nums.size() + 2; i++) tmp ^= i;
        
        // 2. 找出 a,b 中比特位不同的那一位
        int diff = 0;
        while (true) {
            if (((tmp >> diff) & 1) == 1) break;
            else diff++;
        }
        
        // 3. 根据 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. 消失的两个数字
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 2023 年主流编程语言就业前景分析与学习指南
  • Z-Image-Turbo Sugar 脸部 LoRA 模型部署与提示词指南
  • Windows 下配置 KDB+、JupyterQ 与 Python (embedPy) 环境
  • 2023 年数据分析职业发展与薪资前景分析
  • 评价得分计算:权重确定方法
  • AIGC 产品经理学习指南:核心技能、实战项目与面试准备
  • Whisper 模型本地部署完全指南
  • 企业级 AI Agent 全栈架构蓝图:从聊天机器人到智能自动化落地
  • 字节跳动豆包大模型家族与火山方舟 2.0 发布详解
  • 2025 年 AI 大模型发展趋势与企业应用展望
  • 2024 年人工智能风险治理报告解读:构建全链条风控体系
  • 各大学位论文 AIGC 检测率要求汇总及应对策略
  • 2G 内存云服务器部署 Spring Boot + MySQL 实践
  • libgo C++ 协程库使用指南
  • 学术论文降重与去除 AIGC 痕迹的技术方案分析
  • 为什么在人工智能时代选择学习 Python 编程语言
  • 基于 Spring Boot 的上门帮厨管理系统设计与实现
  • AI 系统视角下的大模型发展与技术挑战
  • Seedance 2.0 双分支扩散变换器架构解析与工程实现
  • 利用 Fiddler 代理抓包 JVM 发出的 HTTP 请求

相关免费在线工具

  • 加密/解密文本

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