6365. 将整数减少到零需要的最少操作数

143 阅读1分钟

题目:
给你一个正整数 n ,你可以执行下述操作 任意 次:

  • n 加上或减去 2 的某个

返回使 n 等于 0 需要执行的 最少 操作数。

如果 x == 2i 且其中 i >= 0 ,则数字 x2 的幂。
算法
方法一: 贪心
说一下分析过程,先把两个数的二进制表示列出来
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的个数为1,则进行n - lowbit(n)
  2. 如果从低位到高位连续的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)
}