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

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

位运算在算法优化中常作为提升效率的关键手段,本文通过多个经典案例展示其实际应用。包括利用位图思想判断字符唯一性、借助异或特性快速定位缺失数字、模拟硬件加法逻辑计算整数之和,以及针对重复元素出现的频次统计问题。结合 C++ 代码实例,解析了从基础位操作到复杂逻辑组合的实战技巧,帮助开发者掌握高效的空间与时间优化方案。

监控大屏发布于 2026/3/29更新于 2026/7/2031 浏览

位运算实战技巧

位运算不仅是底层优化的利器,更是解决特定算法问题的捷径。在处理大量数据或对性能要求极高的场景下,合理使用位操作往往能带来显著的空间和时间收益。下面我们通过几个经典题目,看看如何灵活运用这些技巧。

判定字符是否唯一

这道题的核心在于空间优化。既然只需要判断小写字母是否重复,我们可以用一个整数的 32 个比特位来充当哈希表。每一位代表一个字符,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';
            // 先判断该位是否已被置为 1
            if(((bitmap >> e) & 1) == 1) return false;
            // 将当前字符对应的位设为 1
            bitmap |= (1 << e);
        }
        return true;
    }
};

寻找消失的数字

数组包含 [0, n] 中缺失的一个数。利用异或运算的自反性(a^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;
    }
};

两整数之和

在没有加减乘除运算符的情况下如何实现加法?这其实是在模拟 CPU 的加法器逻辑。异或运算实现了无进位加法,而按位与左移则计算出了进位值。只要进位不为 0,就继续循环相加。

class Solution {
public:
    int getSum(int a, int b) {
        while(b){
            int x = a ^ b; // 无进位结果
            // 计算进位,需转为 unsigned 避免符号位干扰
            unsigned int carry = (unsigned int)(a & b) << 1; 
            a = x;
            b = carry;
        }
        return a;
    }
};

只出现一次的数字 II

数组中只有一个数字出现一次,其余都出现三次。这时候不能简单用异或了,因为 x^x^x=x。我们需要统计每一位上 1 出现的总次数,然后对 3 取模。如果某一位的总和模 3 余 1,说明目标数字在该位是 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;
    }
};

只出现一次的数字 III

这次有两个数字各出现一次,其余出现两次。首先将所有数异或,得到的结果是这两个不同数字的异或值 a^b。由于 a!=b,这个结果中至少有一位是 1。找到这一位,就可以把原数组分成两组:该位为 0 的和该位为 1 的。这样两个目标数字会被分到不同的组,而相同的数字依然在同一组,分别异或即可得到结果。

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int tmp = 0;
        for(auto x : nums) tmp ^= x;
        
        // 找出最低位的不同位
        int diff = 0;
        while(!((tmp >> diff) & 1)) diff++;
        
        int a = 0, b = 0;
        for(auto x : nums){
            if((x >> diff) & 1) b ^= x;
            else a ^= x;
        }
        return {a, b};
    }
};

消失的两个数字

这是前面两个问题的组合变体。先将数组元素与 [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(!((tmp >> diff) & 1)) 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. 只出现一次的数字 II
  6. 只出现一次的数字 III
  7. 消失的两个数字
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 基于 NEAT 算法的 Flappy Bird AI 自动通关实现
  • Spring Web MVC 核心概念与实战指南
  • LLaMA-Factory 大模型微调实战:Qwen3 + LoRA
  • Linux 入门实战:文件系统与进程管理
  • 2026年RAG技术演进:基于DeepSeek与Neo4j构建企业知识图谱
  • 基于 DeepSeek 与 Cursor 构建智能代码审查系统实战
  • 从 GAN 到 ChatGPT:AIGC 技术演进与实战应用指南
  • 渗透测试实战:获取并破解 Net-NTLMv2 哈希
  • 鸿蒙金融理财全栈:应用上线、运维监控与持续迭代实践
  • 无监督学习:K-Means 聚类算法 MATLAB 实现
  • 毕业就业信息管理系统:SpringBoot 后端+Vue 前端+MySQL 实现
  • 生成式引擎优化(GEO)与 SEO 的区别及实践指南
  • 揭秘 Secure DM Pairing:为 AI 机器人构建安全私信访问机制
  • 算法实战:利用前缀和解中心下标与数组乘积问题
  • Linux 基础 IO:深入理解软链接与硬链接
  • Java NIO 基础原理与服务端开发指南
  • Neo4j Desktop 安装与使用指南
  • 大模型微调框架对比:Firefly 与 LLaMA Factory 选型指南
  • WebGIS 实战:WKT 转 GeoJSON 技巧与 Leaflet 集成
  • OpenAI 发布 GPT-5.3 Instant:幻觉率降低及 2026 AI 模型排行

相关免费在线工具

  • 加密/解密文本

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