题目:
给你一个正整数 n ,你可以执行下述操作 任意 次:
n加上或减去2的某个 幂
返回使 n 等于 0 需要执行的 最少 操作数。
如果 x == 2i 且其中 i >= 0 ,则数字 x 是 2 的幂。
算法
方法一: 贪心
说一下分析过程,先把两个数的二进制表示列出来
weight: 64 32 16 8 4 2 1
39: 1 0 0 1 1 1
54: 1 1 0 1 1 0
我们先分析39:为了尽快将n变为0,我们可以对n = n + lowbit(n),39变成:
weight: 64 32 16 8 4 2 1
39: 1 0 1 0 0 0
然后我们再进行n = n - lowbit(n):
weight: 64 32 16 8 4 2 1
39: 1 0 0 0 0 0
最后再减去lowbit: n - lowbit(n):
weight: 64 32 16 8 4 2 1
39: 0 0 0 0 0 0
总共进行三次操作,回顾上面的操作过程,我们发现
- 如果从低位到高位连续的1的个数为1,则进行n - lowbit(n)
- 如果从低位到高位连续的1的个数大于1,则进行n + lowbit(n)
这个策略可以使用最少步骤数量。
func minOperations(n int) int {
ans := 0
for n > 0 {
x := lowbit(n)
c1 := 0
// 检查连续的1的个数
for (n & x) > 0{
x = x << 1
c1 ++
}
if c1 == 1 {
ans ++
n = n - lowbit(n)
} else {
n = n + lowbit(n)
ans ++
}
}
return ans
}
func lowbit(x int) int {
return x & ( - x)
}