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

位运算实战:两数之和、单次数字与缺失数字

位运算实战:两数之和、单次数字与缺失数字。通过三个经典算法题深入解析位运算技巧。第一题利用异或实现无进位加法与按位与处理进位,循环求解两数之和;第二题统计所有数字二进制位总和模三,还原唯一出现一次的数字;第三题结合异或性质将缺失两数问题转化为分组异或求解。代码采用 C++ 实现,注重时间复杂度优化与逻辑清晰性。

1qazxsw2发布于 2026/3/30更新于 2026/9/1957 浏览
位运算实战:两数之和、单次数字与缺失数字

35. 两个整数之和

题目链接

题目描述

不使用运算符 + 和 -,计算两整数 a、b 之和。

解题思路

这道题的核心在于理解计算机底层是如何做加法的。我们可以将加法拆解为两部分:

  1. 无进位相加:使用异或运算 ^。例如 1 ^ 1 = 0, 1 ^ 0 = 1,这正好对应二进制加法中不考虑进位的结果。
  2. 进位计算:使用按位与 & 后左移一位 << 1。只有当两个位都是 1 时才会产生进位,且进位需要加到更高一位上。

我们需要不断重复这两个步骤,直到没有进位为止(即进位值为 0)。

C++ 代码实现

class Solution {
public:
    int getSum(int a, int b) {
        // 当进位不为 0 时继续循环
        while (b != 0) {
            // 无进位和
            int sumWithoutCarry = a ^ b;
            // 计算进位并左移
            int carry = (unsigned int)(a & b) << 1;
            
            a = sumWithoutCarry;
            b = carry;
        }
        return a;
    }
};

注意:在 C++ 中,对有符号整数进行左移操作可能会触发未定义行为,因此建议将 a & b 的结果强制转换为 unsigned int 后再移位,以确保逻辑安全。

算法流程解析


36. 只出现一次的数字 II

题目链接

题目描述

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。

解题思路

既然其他数字都出现了三次,那么对于任意一个二进制位,如果该位上所有数字的 1 的个数能被 3 整除,说明目标数字在该位上是 0;否则,目标数字在该位上是 1。

我们可以遍历 32 个比特位,统计数组中所有数字在第 i 位上 1 出现的总次数。对 3 取余,结果即为唯一数字在该位的值。

C++ 代码实现

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret = 0;
        // 遍历 32 位整数的每一位
        for (int i = 0; i < 32; i++) {
            int sum = 0;
            // 统计当前位上 1 的总数
            for (int x : nums) {
                sum += ((x >> i) & 1);
            }
            // 如果 sum % 3 不为 0,说明目标数字该位为 1
            if (sum % 3 != 0) {
                ret |= (1 << i);
            }
        }
        return ret;
    }
};

算法流程解析


38. 消失的两个数字

题目链接

题目描述

给定包含 0..n 中 n 个数的数组 nums,找出其中两个缺失的数字。

解题思路

这道题可以看作是'丢失的数字'和'只出现一次的数字 III'的结合体。

  1. 整体异或:将数组中的所有数字与 [1, n+2] 范围内的所有数字进行异或。根据异或性质 A ^ A = 0,成对出现的数字会抵消,最终结果 ret 等于两个缺失数字的异或值(a ^ b)。
  2. 分组隔离:因为 a 和 b 不同,ret 中至少有一位是 1。找到这个位置(比如第 x 位),说明 a 和 b 在这一位上一个为 0,一个为 1。
  3. 分别异或:利用这一位将原数组和范围数字分成两组。相同的数字必然在同一组,会互相抵消;而 a 和 b 会被分到不同组。分别对两组进行异或,即可得到 a 和 b。

C++ 代码实现

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) {
        int ret = 0;
        int a = 0;
        int b = 0;
        
        // 第一步:计算两个缺失数字的异或值
        for (int num : nums) {
            ret ^= num;
        }
        for (int i = 1; i <= nums.size() + 2; i++) {
            ret ^= i;
        }
        
        // 第二步:找到 ret 中最右侧为 1 的位
        int x = 0;
        while (((ret >> x) & 1) == 0) {
            x++;
        }
        
        // 第三步:根据该位将数字分为两组分别异或
        for (int num : nums) {
            if (((num >> x) & 1) == 0) {
                a ^= num;
            } else {
                b ^= num;
            }
        }
        for (int i = 1; i <= nums.size() + 2; i++) {
            if (((i >> x) & 1) == 0) {
                a ^= i;
            } else {
                b ^= i;
            }
        }
        
        return {a, b};
    }
};

算法流程解析

目录

  1. 35. 两个整数之和
  2. 题目描述
  3. 解题思路
  4. C++ 代码实现
  5. 36. 只出现一次的数字 II
  6. 题目描述
  7. 解题思路
  8. C++ 代码实现
  9. 38. 消失的两个数字
  10. 题目描述
  11. 解题思路
  12. C++ 代码实现

更多推荐文章

查看全部
  • Spark DataFusion Comet 向量化:Rust Native ScanExec 与 Selection Vectors
  • 基于算法的 LLM 代码翻译新范式:解决意图丢失问题
  • C++ 智能指针:内存管理的利器
  • Ollama 模型管理与删除指南及 Open-WebUI 部署实战
  • OpenClaw 开源 AI 智能体:核心原理、功能特性与本地部署
  • JDBC PostgreSQL 连接 URL 参数详解与最佳实践
  • AI 时代产品经理的进化方向与核心能力
  • 基于动态反演和扩展状态观测器的无人机鲁棒反馈线性化自适应姿态控制器
  • 前端弹窗遮罩层背景滚动穿透问题及三种解决方案
  • EasyPostman:开源免费 Postman 替代方案,支持国产化操作系统
  • 医疗 AI 场景下算法编程深度解析
  • MIT 室内场景识别数据集详解与 YOLOv8 分类实战
  • GitHub Copilot 登录失败常见原因与排查指南
  • Ubuntu 20.04 安装无人机地面站 QGroundControl
  • 网络安全就业前景与核心岗位详解
  • Java 中间件:RabbitMQ 消费端限流实战(basicQos 配置)
  • VS Code 连接 Gitee 上传代码实战指南
  • Web 安全学习笔记:网络协议、漏洞攻防与内网渗透指南
  • 基于 Whisper 的本地语音识别与隐私保护方案
  • 宇树 G1 人形机器人 VR 遥操与 IL 开发:xr_teleoperate 到 unitree_IL_lerobot

相关免费在线工具

  • 加密/解密文本

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