Minimum Array End
Problem Description
You are given two integers n and x. You need to construct an array of positive integers nums of size n where:
nums[i] < nums[i + 1]for all0 ≤ i < n - 1(i.e. the array is strictly increasing).- The bitwise AND of all elements of
numsisx.
Return the minimum possible value of nums[n - 1].
Examples
Example 1:Input: n = 3, x = 4 Output: 6 Explanation: The array can be [4, 5, 6]. The bitwise AND of these elements is 4. The last element is 6.
Input: n = 2, x = 7 Output: 15 Explanation: The array can be [7, 15]. The bitwise AND is 7. The last element is 15.
Constraints
1 ≤ n, x ≤ 10⁸
Map the Bits of (n - 1) Into x’s Zero Positions
For the bitwise AND of the array to be x, every element in the array must have all the bits of x set. That is, if a bit is 1 in x, it must be 1 in every element.
To construct the strictly increasing array:
- The first element is
xitself. - For subsequent elements, we want to increment the value while keeping all
1bits ofxlocked. This means we are free to change only the bits that are0inx. - To find the
nth element (which corresponds ton - 1increments starting from index 0), we take the binary representation ofn - 1and map its bits into the0bit positions ofx.
For example, if x = 4 (100 in binary) and n = 3 (n-1 = 2, which is 10 in binary):
- The
0positions inx(from right to left) are at indices 0 and 1. - We map the bits of
2(10in binary) into these positions:- Bit 0 of
2(0) goes to index 0. - Bit 1 of
2(1) goes to index 1.
- Bit 0 of
- The resulting value is
110in binary, which is6.
Solution: Bit Placement
class Solution {
public long minEnd(int n, int x) {
long result = x;
long remaining = n - 1;
// iterate through the bits of result, placing bits of remaining into 0 spots
for (int i = 0; i < 64 && remaining > 0; i++) {
if ((result & (1L << i)) == 0) {
// if bit i of x is 0, place the lowest bit of remaining here
if ((remaining & 1) != 0) {
result |= (1L << i);
}
remaining >>= 1;
}
}
return result;
}
}class Solution:
def minEnd(self, n: int, x: int) -> int:
result = x
remaining = n - 1
# place bits of remaining (n - 1) into the 0 bits of x
i = 0
while remaining > 0:
if (result & (1 << i)) == 0:
if remaining & 1:
result |= (1 << i)
remaining >>= 1
i += 1
return resultclass Solution {
public:
long long minEnd(int n, int x) {
long long result = x;
long long remaining = n - 1;
for (int i = 0; i < 64 && remaining > 0; i++) {
if ((result & (1LL << i)) == 0) {
if (remaining & 1) {
result |= (1LL << i);
}
remaining >>= 1;
}
}
return result;
}
};Complexity Analysis:
- Time Complexity: O(log N + log X). The loop runs at most 64 times since we look at 64-bit representations.
- Space Complexity: O(1).
Where it breaks: the return value must be long (Java) or long long (C++). Even though n and x are both bounded by 10⁸ (which fits in a standard 32-bit signed integer), mapping the bits of n - 1 into the zero spots of x shifts bits up to index 62, which exceeds the 32-bit integer range. Returning a 32-bit integer causes overflow.