📘 LeetCode 3191. Minimum Operations to Make the Integer Zero
题目链接:得到整数零需要执行的最少操作数
1. 题目理解
给定两个整数 num1
和 num2
。
每次操作可以让 num1 -= 2^x + num2
,其中 x ≥ 0
。
问题:最少操作次数使得 num1 = 0。如果无法做到,返回 -1。
2. 关键观察
操作公式:
num1 → num1 - (2^x + num2)
经过 k
次操作后:
num1_final = num1 - (2^x1 + num2) - (2^x2 + num2) - ... - (2^xk + num2)
= num1 - k*num2 - (2^x1 + 2^x2 + ... + 2^xk)
要求最后结果为 0:
num1 - k*num2 = (2^x1 + 2^x2 + ... + 2^xk)
👉 右边是 若干个 2 的幂之和,也就是二进制拆分。
3. 约束条件
设
m = num1 - k*num2
则必须满足:
m ≥ 0
(否则无法做到非负和)。m
的二进制中 1 的个数 ≤ k(因为每次操作产生一个 2^x,可以"合并"成更大的 2^x)。m ≤ k
(因为最小能产生的和是k*1 = k
)。
4. 解题思路
-
从
k = 1
开始枚举操作次数。 -
计算
m = num1 - k*num2
。 -
如果
m < 0
→ 直接停止。 -
如果
bitcount(m) ≤ k ≤ m
→ 这是一个合法解。bitcount(m)
= 二进制中 1 的数量。k ≤ m
保证 2^x 的和不小于 k。
-
返回第一个满足条件的
k
。 -
如果一直没找到,返回 -1。
5. 示例
示例 1
num1 = 5, num2 = 2
- k=1 → m=5-2=3,bitcount(3)=2 > 1 ❌
- k=2 → m=5-4=1,bitcount(1)=1 ≤ 2,且 2 ≤ 1 ❌
- k=3 → m=5-6=-1 ❌
→ 返回 -1。
示例 2
num1 = 12, num2 = 2
- k=1 → m=10 (1010),bitcount=2 > 1 ❌
- k=2 → m=8 (1000),bitcount=1 ≤ 2,且 2 ≤ 8 ✅
→ 答案是 2。
6. 总结口诀
关键等式:
num1 - k*num2 = m = sum(2^xi)
判定条件:
- m ≥ 0
- bitcount(m) ≤ k ≤ m
7. 常见坑点
- 忘记
m
必须非负。 - 只检查了
bitcount(m) ≤ k
,却忘了k ≤ m
。 - 操作次数可能很大,实际代码里只需要枚举到 合理上界(比如 60,因为 2^60 已经很大)。
long x = num1 - (long) num2 * k
记得开long
java
class Solution {
public int makeTheIntegerZero(int num1, int num2) {
int k = 1;
while (true) {
long x = num1 - (long) num2 * k;
if (x < k) {
return -1;
}
if (k >= Long.bitCount(x)) {
return k;
}
k++;
}
}
}