📅  最后修改于: 2023-12-03 15:36:41.591000             🧑  作者: Mango
给定一个正整数 N,你可以执行以下操作:
你需要使用以上操作尽可能地减少 N,直到它变为 0。编写一个函数来最小化执行操作的次数,并返回其次数。
对于 N 的奇偶性,我们可以分别考虑。
当 N 是偶数时,直接将其除以 2,操作次数加 1 即可。
当 N 是奇数时,我们可以观察比 N 大 1 和比 N 小 1 的两个数,它们的二进制最多只有一位不同。如果将这一位从 0 或 1 切换即可转换成 N。那么我们应该选择哪一个数呢?直觉上,我们应该选择与 N 的二进制表示差异比较少的那个数,因为这样可以减少操作数。
为了找到与 N 差异最少的那个数,我们可以先将 N 的二进制表示取反,然后按位与上 N 的二进制表示,这样能够得到二进制表示中最右边的 1 及其之后的位变成 0,而其他位全变成 0。将它与 N 做异或运算,结果就是比 N 的二进制表示差异最少的那个数。
Python 代码:
def minOperations(n: int) -> int:
cnt = 0
while n:
if n % 2 == 0:
n //= 2
else:
n ^= 1 if n == 1 else (n & -n)
cnt += 1
return cnt - 1
时间复杂度:$O(\log N)$
空间复杂度:$O(1)$
将 N 转换成 0 需要的最小操作数,本题的思路较为巧妙,需要一定的数学基础才能理解。不过实现起来并不困难,而且时间复杂度非常优秀。