Minimum Operations to Make the Integer Zero
Overview

Minimum Operations to Make the Integer Zero

September 5, 2025
1 min read
leetcode-2749

leet code - #2749 (medium)

You are given two integers num1 and num2.

In one operation, you can choose integer i in the range [0, 60] and subtract 2^i + num2 from num1.

Return the integer denoting the minimum number of operations needed to make num1 equal to 0.

If it is impossible to make num1 equal to 0, return -1.

Example 1:

Input: num1 = 3, num2 = -2
Output: 3
Explanation: We can make 3 equal to 0 with the following operations:
- We choose i = 2 and subtract 2^2 + (-2) from 3, 3 - (4 + (-2)) = 1.
- We choose i = 2 and subtract 2^2 + (-2) from 1, 1 - (4 + (-2)) = -1.
- We choose i = 0 and subtract 2^0 + (-2) from -1, (-1) - (1 + (-2)) = 0.
It can be proven, that 3 is the minimum number of operations that we need to perform.

Example 2:

Input: num1 = 5, num2 = 7
Output: -1
Explanation: It can be proven, that it is impossible to make 5 equal to 0 with the given operation.

Constraints:

  • 1 <= num1 <= 10^9
  • -10^9 <= num2 <= 10^9

Solution

class Solution {
public:
int makeTheIntegerZero(int num1, int num2) {
// check if (num1 - k * num2) is possible w/ k terms of (power of 2)
int k = 1;
while (true) {
// subtract num2 for k times (step k)
long long num = num1 - (long long)num2 * k;
// if we choose i for only 0, at least k is needed (1+1+1+1.... = k)
if (num < k) return -1;
// when num of set bits is <= k, we can make num w/ k terms of (power of 2)
else if (bitCnt(num) <= k) return k;
// check for next step
++k;
}
}
// Brian Kernighan’s Algorithm
int bitCnt(long long num) {
int cnt = 0;
while (num != 0) {
++cnt;
num &= (num-1);
}
return cnt;
}
// or use __builtin_popcountll(num)
int bitCnt2(long long num) {
return __builtin_popcountll(num);
}
};

k 번 연산의 의미

연산을 k 번 수행한다는 것은 num1 에서 num2k 번 빼고, 추가로 k 개의 2의 거듭제곱 ( 2i2^i 형태의 수 ) 을 빼는 것과 같음.

// convert this:
num1_final = num1 - k * num2 - (2^i_1 + 2^i_2 + ... + 2^i_k)
// to this:
num1 - k * num2 = 2^i_1 + 2^i_2 + ... + 2^i_k

“x라는 숫자를 k개의 2의 거듭제곱의 합으로 표현할 수 있는가?” 가 문제의 핵심이 됨.

k 의 유효성 검증 조건

xk 개의 2의 거듭제곱 합으로 나타낼 수 있는지 판별하기 위한 두 가지 조건이 있음:

  1. k 의 하한(Lower Bound): k >= popcnt(x)

x를 이진수로 표현하는 것 자체가 x를 2의 거듭제곱의 합으로 나타내는 가장 효율적인 방법임. 예를 들어 x = 13 이면 이진수로 1101이고, 이는 23+22+202^3 + 2^2 + 2^0. 즉, 13을 표현하려면 최소 3개의 2의 거듭제곱이 필요하며, 따라서 k는 최소 popcnt(x)보다는 크거나 같아야 함.

  1. k의 상한(Upper Bound): k <= x

k 개의 2의 거듭제곱으로 만들 수 있는 가장 작은 합은 가장 작은 2의 거듭제곱인 20=12^0 = 1k 번 더하는 것임. 그 합은 k가 되며, 따라서 우리가 만들려는 숫자 x는 최소한 k보다는 크거나 같아야 함.

탐색 종료 조건

우리는 k 를 1부터 계속 증가시키며 탐색함. 이때 x = num1 - k * num2 의 변화를 관찰해 보면, k 가 1씩 증가할 때마다 xnum2 만큼 계속 감소함. 즉, k 는 계속 커지는데 x 는 계속 작아짐.

언젠가는 k > x가 되는 지점이 올 수 있으며, k 의 상한 조건(k <= x) 에 따라, 이 지점부터는 더 이상 유효한 k 를 찾을 수 없음. k 가 더 커지면 이 부등식은 계속 성립할 것이기 때문.

따라서, 탐색 중에 처음으로 k > x 가 되는 순간, 더 이상 해를 찾을 수 없다고 판단하고 즉시 -1을 반환하며 탐색을 종료할 수 있음.