You are given a 2D array queries, where queries[i] is of the form [l, r]. Each queries[i] defines an array of integers nums consisting of elements ranging from l to r, both inclusive.
In one operation, you can:
Select two integers a and b from the array.
Replace them with floor(a / 4) and floor(b / 4).
Your task is to determine the minimum number of operations required to reduce all elements of the array to zero for each query. Return the sum of the results for all queries.
Input: queries =[[1,2],[2,4]]Output: 3Explanation:
For `queries[0]`:* The initial array is`nums = [1, 2]`.* In the first operation, select `nums[0]` and `nums[1]`. The array becomes `[0, 0]`.* The minimum number of operations required is1.For `queries[1]`:* The initial array is`nums = [2, 3, 4]`.* In the first operation, select `nums[0]` and `nums[2]`. The array becomes `[0, 3, 1]`.* In the second operation, select `nums[1]` and `nums[2]`. The array becomes `[0, 0, 0]`.* The minimum number of operations required is2.The output is`1 + 2 = 3`.
Input: queries =[[2,6]]Output: 4Explanation:
For `queries[0]`:* The initial array is`nums = [2, 3, 4, 5, 6]`.* In the first operation, select `nums[0]` and `nums[3]`. The array becomes `[0, 3, 4, 1, 6]`.* In the second operation, select `nums[2]` and `nums[4]`. The array becomes `[0, 3, 1, 1, 1]`.* In the third operation, select `nums[1]` and `nums[2]`. The array becomes `[0, 0, 0, 1, 1]`.* In the fourth operation, select `nums[3]` and `nums[4]`. The array becomes `[0, 0, 0, 0, 0]`.* The minimum number of operations required is4.The output is4.
Each operation reduces two numbers by dividing them by 4 (floor). The process is similar to reducing the largest numbers first, and the minimum number of operations is determined by the maximum number of times you need to divide any number in the range by 4 until it reaches zero. Since you can pair up numbers, the answer for each query is the ceiling of half the sum of the number of divisions needed for each number.
classSolution {
public:longlong minOperations(std::vector<std::vector<int>>& queries) {
longlong ans =0;
for (auto& q : queries) {
int l = q[0], r = q[1];
longlong cnt =0;
for (int x = l; x <= r; ++x) {
int t = x;
while (t) {
t /=4;
++cnt;
}
}
ans += (cnt +1) /2;
}
return ans;
}
};
classSolution {
publiclongminOperations(int[][] queries) {
long ans = 0;
for (int[] q : queries) {
int l = q[0], r = q[1];
long cnt = 0;
for (int x = l; x <= r; ++x) {
int t = x;
while (t > 0) {
t /= 4;
cnt++;
}
}
ans += (cnt + 1) / 2;
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
funminOperations(queries: Array<IntArray>): Long {
var ans = 0Lfor (q in queries) {
val l = q[0]
val r = q[1]
var cnt = 0Lfor (x in l..r) {
var t = x
while (t > 0) {
t /=4 cnt++ }
}
ans += (cnt + 1) / 2 }
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from typing import List
classSolution:
defminOperations(self, queries: List[List[int]]) -> int:
ans: int =0for l, r in queries:
cnt: int =0for x in range(l, r +1):
t: int = x
while t:
t //=4 cnt +=1 ans += (cnt +1) //2return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
impl Solution {
pubfnmin_operations(queries: Vec<Vec<i32>>) -> i64 {
letmut ans: i64=0;
for q in queries {
let (l, r) = (q[0], q[1]);
letmut cnt: i64=0;
for x in l..=r {
letmut t = x;
while t >0 {
t /=4;
cnt +=1;
}
}
ans += (cnt +1) /2;
}
ans
}
}
⏰ Time complexity: O(Q * N * logM) — For each query, for each number in the range, we divide by 4 until zero. Q = number of queries, N = range size, M = max number value.
🧺 Space complexity: O(1) — Only a few variables are used, no extra space proportional to input size.
To reduce a number n to zero by repeated division by 4, we need floor(log₄(n)) + 1 operations. This means we can group numbers by the number of divisions required:
Numbers in [1, 3] (i.e., from 4⁰ to 4¹ - 1) require 1 division.
Numbers in [4, 15] (i.e., from 4¹ to 4² - 1) require 2 divisions.
Numbers in [16, 63] (i.e., from 4² to 4³ - 1) require 3 divisions.
… and so on.
This observation allows us to efficiently count the total number of operations needed for any interval.
classSolution {
publiclongminOperations(int[][] queries) {
long ans = 0;
for (int[] q : queries) {
long l = q[0], r = q[1], ops = 0;
long prev = 1;
for (int d = 1; d < 17; d++) {
long cur = prev * 4L;
long left = Math.max(l, prev), right = Math.min(r, cur - 1);
if (right >= left) ops += (right - left + 1) * d;
prev = cur;
}
ans += (ops + 1) / 2;
}
return ans;
}
}
classSolution {
funminOperations(queries: Array<IntArray>): Long {
var ans = 0Lfor (q in queries) {
var l = q[0].toLong()
var r = q[1].toLong()
var ops = 0Lvar prev = 1Lfor (d in1..16) {
val cur = prev * 4Lval left = maxOf(l, prev)
val right = minOf(r, cur - 1)
if (right >= left) ops += (right - left + 1) * d
prev = cur
}
ans += (ops + 1) / 2 }
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from typing import List
classSolution:
defminOperations(self, queries: List[List[int]]) -> int:
ans =0for l, r in queries:
ops =0 prev =1for d in range(1, 17):
cur = prev *4 left = max(l, prev)
right = min(r, cur -1)
if right >= left:
ops += (right - left +1) * d
prev = cur
ans += (ops +1) //2return ans
impl Solution {
pubfnmin_operations(queries: Vec<Vec<i32>>) -> i64 {
letmut ans: i64=0;
for q in queries {
let l = q[0] asi64;
let r = q[1] asi64;
letmut ops: i64=0;
letmut prev: i64=1;
for d in1..17 {
let cur = prev *4;
let left = std::cmp::max(l, prev);
let right = std::cmp::min(r, cur -1);
if right >= left {
ops += (right - left +1) * d;
}
prev = cur;
}
ans += (ops +1) /2;
}
ans
}
}