You are given an integer array nums
. You have an integer array arr
of the same length with all values set to 0
initially. You also have the following modify
function:
You want to use the modify function to convert arr
to nums
using the minimum number of calls.
Return the minimum number of function calls to make nums
from arr
.
The test cases are generated so that the answer fits in a 32-bit signed integer.
Example 1:
Input: nums = [1,5] Output: 5 Explanation: Increment by 1 (second element): [0, 0] to get [0, 1] (1 operation). Double all the elements: [0, 1] -> [0, 2] -> [0, 4] (2 operations). Increment by 1 (both elements) [0, 4] -> [1, 4] -> [1, 5] (2 operations). Total of operations: 1 + 2 + 2 = 5.
Example 2:
Input: nums = [2,2] Output: 3 Explanation: Increment by 1 (both elements) [0, 0] -> [0, 1] -> [1, 1] (2 operations). Double all the elements: [1, 1] -> [2, 2] (1 operation). Total of operations: 2 + 1 = 3.
Example 3:
Input: nums = [4,2,5] Output: 6 Explanation: (initial)[0,0,0] -> [1,0,0] -> [1,0,1] -> [2,0,2] -> [2,1,2] -> [4,2,4] -> [4,2,5](nums).
Constraints:
1 <= nums.length <= 105
0 <= nums[i] <= 109
This problem asks for the minimum number of operations to transform an array of zeros into a target array nums
using two operations:
The solution uses a greedy approach combined with bit manipulation for efficiency. The key insight is that we can analyze the binary representation of each number in nums
.
Algorithm:
Count Set Bits: For each number n
in nums
, count the number of set bits (1s) in its binary representation. This represents the number of increment operations needed to reach that number if we start from 0, assuming we can double at any time. Sum these counts.
Find Maximum and its Leading Zeros: Find the maximum number mx
in nums
. The number of leading zeros in mx
's binary representation (excluding the leading 1) indicates how many doubling operations are needed to reach a number greater than or equal to mx
. This is because each doubling operation shifts the bits to the left by 1.
Total Operations: The total minimum operations are the sum of the set bits (from step 1) plus the number of doubling operations (from step 2).
Time Complexity Analysis:
nums
takes O(N) time, where N is the length of nums
.Integer.bitCount()
or similar functions) for each number takes O(log M) time in the worst case for a number M, but it is typically very fast, practically considered constant time in most cases.Therefore, the overall time complexity is O(N), dominated by the iteration through the input array.
Space Complexity Analysis:
The solution uses only a few variables to store intermediate results. The space complexity is O(1), which is constant.
Code Explanation (Python):
class Solution:
def minOperations(self, nums: List[int]) -> int:
return sum(v.bit_count() for v in nums) + max(0, max(nums).bit_length() - 1)
This concise Python code leverages the built-in bit_count()
method (available in Python 3.10+) to efficiently count set bits. bit_length()
gives the number of bits needed to represent a number. The max(0, ...)
handles the case where nums
contains only zeros.
Code Explanation (Java):
class Solution {
public int minOperations(int[] nums) {
int ans = 0;
int mx = 0;
for (int v : nums) {
mx = Math.max(mx, v);
ans += Integer.bitCount(v); // Counts set bits
}
// Integer.toBinaryString(mx).length() -1 is equivalent to the calculation 31 - Integer.numberOfLeadingZeros(mx) but more concise.
ans += Integer.toBinaryString(mx).length() - 1;
return ans;
}
}
The Java code uses Integer.bitCount()
for set bit counting and a similar approach to determine the number of doubling operations.
The C++ and Go code follow a similar approach but use their respective bit manipulation functions. The Go code is slightly less concise as it explicitly implements the set bit count instead of using a built-in function.