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

面试题 17.19 消失的两个数字:位运算实战解析

面试题 17.19 寻找数组中缺失的两个数字。核心思路利用异或运算特性,将原数组与完整区间 [1, n+2] 进行异或,得到两个缺失数的异或值。通过提取该值的最低有效位(或遍历找到任意不同比特位),将数字分为两组分别异或,从而分离出两个缺失数。该方法时间复杂度 O(n),空间复杂度 O(1),是处理此类问题的经典位运算技巧。

星河入梦发布于 2026/3/25更新于 2026/6/2822 浏览
面试题 17.19 消失的两个数字:位运算实战解析

面试题 17.19 消失的两个数字

题目链接:

面试题 17.19. 消失的两个数字 - 力扣(LeetCode)

题目描述:

题目描述

题目示例:

题目示例

解题思路

这道题本质上是 268. 丢失的数字 和 260. 只出现一次的数字 III 的结合体。

核心在于利用异或运算的性质:

  1. 相同的数异或为 0。
  2. 任何数与 0 异或为其本身。

我们将数组中的元素与区间 [1, n+2] 的所有整数一起异或。由于除了两个缺失的数字外,其他数字都出现了两次(一次在数组,一次在区间),它们会相互抵消。最终剩下的结果就是那两个缺失数字的异或值(记为 a ^ b)。

既然 a != b,那么 a ^ b 的结果中至少有一位是 1。我们可以根据这一位将所有的数字分为两组,每组包含一个缺失数字。再分别对两组进行异或,即可还原出 a 和 b。

C++ 实现方案

这里提供两种常见的位运算实现方式。

方法一:提取最低有效位

直接利用 x & (-x) 快速提取二进制中最右侧的 1。

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) {
        int temp = 0;
        // 数组元素异或
        for (auto& x : nums) temp ^= x;
        // 区间 [1, n+2] 异或
        for (int i = 1; i <= nums.size() + 2; i++) temp ^= i;
        
        // temp 现在是 a ^ b,提取最右边的 1
        int ls = temp & (-temp);
        
        int a = 0, b = 0;
        // 分组异或
        for (auto& x : nums) {
            if (x & ls) a ^= x;
            else b ^= x;
        }
        for (int i = 1; i <= nums.size() + 2; i++) {
            if (i & ls) a ^= i;
            else b ^= i;
        }
        return {a, b};
    }
};
方法二:循环查找差异位

如果不熟悉位运算技巧,也可以循环移位找到第一个不同的比特位。

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

算法总结

笔记展示

笔记展示


这种位运算解法避免了额外的哈希表开销,空间复杂度仅为 O(1),非常适合面试场景下的性能要求。理解异或消去律和分组思想,能解决很多看似复杂的计数问题。

目录

  1. 面试题 17.19 消失的两个数字
  2. 解题思路
  3. C++ 实现方案
  4. 方法一:提取最低有效位
  5. 方法二:循环查找差异位
  6. 算法总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • SQL Server 2025 数据库安装指南
  • Stable Diffusion 模型原理与本地部署实践
  • LLM Agent 反思工作流进阶:Self-Refine、CRITIC 与 Reflexion 技术解析
  • Python Collections 模块核心数据结构与工具详解
  • Linux 线程控制详解:资源管理与实战操作
  • Java 8 基础核心知识梳理:从运算符到面向对象
  • 大模型应用开发实战指南:基于 GPT-4 和 ChatGPT 的核心技术与实践
  • Spring 配置文件加载路径:classpath、file、URL 与 Web 容器路径
  • 用 Prompt 生成正则表达式进行文本匹配实战指南
  • Llama-2-7b 昇腾 NPU 部署与性能测评实战
  • 网络安全入门指南:技术方向与学习路线详解
  • Virt-A-Mate v1.22 中文汉化整合版介绍
  • Python 字符串格式化、编码与深浅拷贝详解
  • 双指针算法:两数之和与三数之和
  • TurboDiffusion 视频压缩:H.264 编码体积优化技巧
  • Python 爬虫副业可行性分析与技术入门指南
  • 利用 AI Agent 提升 Java 后端 Spring Cloud 开发效率
  • Linux 信号保存与递达机制详解
  • HarmonyOS 底部导航栏组件 rc_concave_tabbar 使用指南
  • RAG 实战:基于 Gradio 构建本地文件上传与对话 UI 界面

相关免费在线工具

  • 加密/解密文本

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