


cpp
class Solution {
public:
int minimumOneBitOperations(int n) {
if (n == 0) {
return 0;
}
int x = 31 - __builtin_clz(n);
return (1 << (x + 1)) - 1 - minimumOneBitOperations(n - (1 << x));//抵消反向操作
}
};
方法二:迭代
思路与算法
我们可以将方法一的递归改成迭代。这样的好处在于:
- 我们不需要显式求解出 n 的位数 x;
- 省去了递归需要的栈空间。
代码
cpp
class Solution {
public:
int minimumOneBitOperations(int n) {
int ans = 0; // 存储最终的最少操作次数
int sign = 1; // 符号位,控制当前位的贡献是加还是减,初始为正
// 遍历二进制的第29位到第0位(覆盖了32位整数中可能出现1的大部分位置)
for (int i = 29; i >= 0; i--) {
// 检查n的第i位是否为1(1<<i是第i位为1的掩码)
if (n & (1 << i)) {
// 若第i位为1,累加其贡献值:sign * (2^(i+1) - 1)
ans += sign * ((1 << (i + 1)) - 1);
// 翻转符号(下一个1的贡献会是相反的符号)
sign = -sign;
}
}
return ans;
}
};
按照二进制位从高到低的顺序,根据每个 1 的位置计算其基准操作次数,再通过符号交替体现位之间的抵消关系,最终累加得到总操作次数。