You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++寻找下一个更大同1数算法:/pivot与>>2操作解析

问题解答:寻找比n大且二进制1的个数相同的最小数

先看你给出的代码:

int solution(int n) {
    int pivot = n & -n;
    int before = ((n ^ (n + pivot)) / pivot) >> 2;
    return (n + pivot) | before;
}

下面拆解核心部分((n ^ (n + pivot)) / pivot) >> 2的作用,重点解释/pivot和>>2的必要性:

核心逻辑回顾

找比n大、二进制1的个数相同的最小数,本质是二进制版的「下一个排列」:

  • 第一步:把n最右边的1进位(对应代码里的n + pivot),这会让该位置的1变0,向左找到第一个0变1,中间的所有1全变0。此时得到的数比n大,但1的个数比n少(少了中间那些变成0的1)。
  • 第二步:把第一步中丢失的那些1,重新放到结果的最右边低位,保证1的个数和n一致,同时数最小。before就是用来生成这些需要补回去的1的。

逐部分解释

1. n ^ (n + pivot)

n和n+pivot的异或结果,会标记出两者所有不同的位——也就是从pivot位置(最右边的1)到进位后新1的位置之间的所有位,这些位的二进制全是1。
举个例子:n=6(二进制0110),pivot=2(0010),n+pivot=8(1000),异或结果是0110 ^ 1000 = 1110,也就是第1、2、3位全是1。

2. / pivot的作用

pivot是2^k(因为是n的最低有效置位,二进制是10...0),除以pivot等价于右移k位,把刚才的异或结果(全1序列)对齐到最低位。
还是上面的例子:1110 / 2 = 111(二进制),把原来在高位的全1序列挪到了最低位,方便后续统一处理。如果不做这一步,后续右移的位数会随pivot的位置变化而改变,无法用固定操作处理。

3. >>2的作用

刚才得到的全1序列,前两位1对应的是:

  • 进位产生的新1的位置(原来的0变1,异或后为1)
  • pivot本身的位置(原来的1变0,异或后为1)

这两位的变化已经包含在n+pivot里了,我们需要的是剩下的1——也就是n中原本在pivot左边的连续1,这些1在n+pivot里被变成了0,需要补回到结果的最低位,才能保证1的个数和n一致。
右移2位正好可以去掉前两位无关的1,留下需要补的1序列:

  • 例子n=6:111 >> 2 = 1(二进制),把这个1补到n+pivot=8的最低位,得到1000 | 0001 = 1001(9),正确。
  • 例子n=7(0111):n+pivot=8(1000),异或结果1111,除以1得1111,>>2得11(3),最终8 | 3 = 11(1011),正确。
  • 例子n=9(1001):异或结果0011,除以1得0011,>>2得0,最终1010 | 0 = 1010(10),正确。

最终逻辑总结

(n + pivot)完成了进位操作,before生成了需要补回的最低位1序列,两者按位或就得到了比n大、二进制1的个数相同的最小数。

内容的提问来源于stack exchange,提问作者git546

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:24:52