当前位置: 首页 > news >正文

LeetCode 1009 476 数字的补数

LeetCode 1009 & 476 数字的补数

问题描述

给定一个正整数(或非负整数),输出它的补数。补数是对该数的二进制表示(不包含前导零)按位取反的结果。
例如:5 的二进制是101,取反得010,即十进制 2。

LeetCode 1009 题名为“十进制整数的补码”,LeetCode 476 题名为“数字的补数”,两者本质完全相同。


解法一:逐位取反法(对应 LeetCode 1009 代码)

classSolution{public:intbitwiseComplement(intn){if(!n)return1;// 特殊情况:0 的二进制取反应为 1intres=0;for(inti=0;1<<i<=n;i++)// 遍历有效位,直到 2^i 超过 nres|=!(n>>i&1)<<i;// 取出第 i 位,取反后左移 i 位,累加到结果returnres;}};

思路解析

  • 核心思想:逐位处理原数的二进制有效位,对每一位取反后构建新数。
  • 步骤
    1. n == 0,直接返回1(二进制0取反为1)。
    2. 从低位到高位循环,i表示当前位,循环条件1 << i <= n保证只处理有效位(忽略前导零)。
    3. (n >> i) & 1取出第i位的值(0 或 1)。
    4. 逻辑非!将位值取反:!0 = 1!1 = 0
    5. 将取反后的值左移i位,放回原来的位权位置,通过按位或|=累加到结果res
    6. 循环结束,res即为补数。

复杂度分析

  • 时间复杂度:O(log n),循环次数等于 n 的二进制位数。
  • 空间复杂度:O(1),只使用了常数变量。

解法二:掩码取反法(对应 LeetCode 476 代码)

classSolution{public:intfindComplement(intnum){if(!num)return1;// 特殊情况处理intcnt=0,x=num;while(x){// 统计有效位数x>>=1;cnt++;}// 构造低 cnt 位全 1 的掩码,与 ~num 按位与,保留低位return~num&((1ll<<cnt)-1);}};

思路解析

  • 核心思想:先确定原数的有效位数,构造一个掩码,将取反后的结果截断到有效位。
  • 步骤
    1. num == 0,直接返回1
    2. 统计有效位数cnt:将num不断右移直到 0,每移一次计数加 1。
    3. 构造掩码mask = (1ll << cnt) - 1,即低cnt位全为 1 的二进制数(使用1ll防止左移溢出 int 范围)。
    4. num按位取反得~num,此时高位(超出有效位)也被取反,与掩码按位与&后,高位清零,只保留低cnt位,即为正确补数。

复杂度分析

  • 时间复杂度:O(log n),统计位数需要循环,但取反和与运算是 O(1)。
  • 空间复杂度:O(1)。

两种解法对比

对比维度解法一(逐位取反)解法二(掩码取反)
核心思想逐位遍历原数,取反后构建新数先求位数,构造掩码,再取反截断
时间复杂度O(log n)(循环位数次)O(log n)(统计位数),位运算 O(1)
空间复杂度O(1)O(1)
代码简洁性较直观,适合初学者简洁,利用位运算技巧
边界处理均需单独处理 n=0 的情况均需单独处理 n=0 的情况
潜在问题掩码左移需用1ll避免溢出(int 最大 31 位时左移 31 位可能溢出)

共同点

  • 都正确处理了不包含前导零的二进制取反。
  • 都对n == 0做了特殊处理(返回 1)。
  • 均基于位运算实现,未借助字符串转换。

不同点

  • 实现方式:解法一在循环中直接计算结果,解法二先统计位数再使用取反和掩码。
  • 取反手段:解法一用逻辑非!配合移位实现位取反;解法二直接用按位取反~,再通过与掩码结合。
  • 溢出考虑:解法二必须注意掩码构造时的溢出问题,使用1ll转为 long long 是必要的。

总结

两道题本质相同,解法各有特色。

  • 解法一(逐位取反)思路直观,适合初学者理解二进制位操作。
  • 解法二(掩码取反)代码更简洁,利用掩码一次完成截断,体现了位运算的灵活性,但在使用时需留意数据范围。

掌握这两种解法有助于加深对位运算和二进制表示的理解,在实际开发中可根据场景选择合适的方法。

http://www.jsqmd.com/news/468510/

相关文章:

  • 职场上要懂的思维模型系列(第一章)
  • 5.7 化学反应速率 化学平衡
  • 什么是纵深防护
  • AcWing 3473. 鸡兔同笼
  • 2026 如何快速接入外汇行情 API - 实战指南
  • phar反序列化专题
  • Gitlab安装与使用
  • 迅雷下载速度慢怎么办_教你如何提高30倍
  • OpenClaw实战-NAS配置从0到1详细教程及踩坑记录
  • 195.s域的1/s采用双线性变换法变到Z域如何实现,采用双线性变换法
  • 分析和预测快速约会中双方能否成功配对
  • DRAM内存访问协议核心解析:DRAM命令交互与时序约束全解(JEDEC通用标准)
  • 鸿蒙常见问题分析二十四:ListItemGroup如何使用三元运算符
  • Go 语言基础进阶:指针、init、匿名函数/闭包、defer
  • RabbitMQ整合springboot
  • Java基于微信小程序的社区垃圾回收管理系统【附源码、文档说明】
  • 2026年知网AIGC检测不通过?这4款降AI率工具亲测有效
  • 2026年东北乡土苗木标杆基地最新推荐:云杉营养钵苗、东北红松苗、红松小苗、红松大苗1-6米高、红松营养钵苗、水曲柳苗、靖宇县宜达苗木基地,筑牢绿化种植品质根基 - 海棠依旧大
  • MCP Server简介
  • 大数据领域ClickHouse的缓存机制分析
  • 【OpenClaw】使用教程
  • C++中的访问者模式变体
  • cgroups实战:如何有效管理系统资源
  • 2026年3月靖宇县苗木基地最新推荐榜单:云杉、红松、水曲柳、云杉树苗、东北云杉、东北云杉大苗1-8米、营养钵云杉等苗木选择指南 - 海棠依旧大
  • 把音乐库搬上云端:Navidrome 自托管音乐服务器搭建指南
  • Flutter 三方库 pip 的鸿蒙化适配指南 - 实现标准化的画中画(Picture-in-Picture)模式、支持视频悬浮窗与多任务并行交互
  • 202603周赛新D题
  • Json在线工具使用说明
  • 上课听得懂 一考试就低分!这样选学习机 彻底打通 “会→对→高分” - 海淀教育研究小组
  • 基于ArcScene的裸眼立体图制作说明