#3314
Easy Algorithms Construct the minimum bitwise array i
Array Bit Manipulation
85.3% acceptance
Feb 23, 2026
414
52
You are given an array nums consisting of n prime integers.
You need to construct an array ans of length n, such that, for each index i, the bitwise OR of ans[i] and ans[i] + 1 is equal to nums[i], i.e. ans[i] OR (ans[i] + 1) == nums[i].
Additionally, you must minimize each value of ans[i] in the resulting array.
If it is not possible to find such a value for ans[i] that satisfies the condition, then set ans[i] = -1.
Solution
Rust
Time O(2^n)
Space O(n)
impl Solution {
pub fn min_bitwise_array(nums: Vec<i32>) -> Vec<i32> {
// For prime p: p is odd (except 2).
// x OR (x+1) = p means: x and x+1 together cover all bits of p.
// x+1 is x with lowest 0-bit set to 1 and all lower bits cleared.
// For x OR (x+1) = p: the lowest bit of p must be cleared in x (since x+1 sets it).
// If p is prime and odd: p = ...1 in binary, lowest bit is 1.
// x OR (x+1): if x is even, x+1 = x|1, so x OR (x+1) = x|1. For this = p = odd: x = p & !1 = p-1?
// No: x = p^1 = p with last bit flipped = p-1 (since p is odd). Check: (p-1) OR p = p?
// (p-1) for odd p: last bit becomes 0, rest same. OR p: same as p. Yes! So ans = p-1 when p is odd prime.
// But for 2: 2 is even prime. x OR (x+1) = 2 means x=1? 1 OR 2 = 3 ≠ 2. So -1.
// For odd prime p: clear the lowest set bit of p, i.e., p & (p-1)? No.
// Wait: if p is 5 = 101, then p-1 = 4 = 100. 4 OR 5 = 101 = 5. ✓
// If p is 7 = 111, then p-1 = 6 = 110. 6 OR 7 = 111 = 7. ✓
// If p is 11 = 1011, p-1 = 1010. 1010 OR 1011 = 1011 = 11. ✓ But expected 9.
// Hmm, 9 = 1001. 1001 OR 1010 = 1011 = 11. ✓. And 9 < 10, so we need MINIMUM.
// So p-1 is not always the minimum.
//
// Key insight: x OR (x+1) = p means x and x+1 differ only in the lowest bit of x.
// More precisely: x+1 flips the lowest 0-bit of x and clears all lower bits.
// For x OR (x+1) = p: we need to find which bit k to "split" on:
// If bit k of p is 0, and all bits below k of p are 1: set x = p with bit k cleared,
// and all bits below k set to 0... Actually:
// x = p with bit k set to 0 and bits below k cleared: x = p ^ (2^k - 1) if p has bits 0..k-1 all 1
// Actually for odd p: the LSB is 1. x OR (x+1) where x is even: x+1 = x | 1 so x|x+1 = x|1.
// This equals p iff x = p ^ 1 = p & !1 = p - 1 (since p is odd).
// But we want MINIMUM. We could also find positions where a 0 bit can be used.
// For p = 11 = 1 0 1 1: lowest 0-bit position is bit 2 (0-indexed).
// x = p with bit 2 cleared = 1011 & !0100 = 1011 & 1011 = ... wait, bit 2 of 1011 is 0 already!
// p = 11 in binary = 1011. The 0-bits are at position 2.
// If we use bit k=2: x must have bit k as 0 (since x+1 sets it), bits above k same as p, bits below k all 1 (0 to k-1 all 1).
// x = (p with bit k cleared, bits 0..k-1 set to all 1 except the lowest...)
// Actually: x = (p >> (k+1)) << (k+1) | (2^k - 1)
// i.e., x = p & ~((1 << (k+1)) - 1) | ((1 << k) - 1)
// For p=11=1011, k=2: x = 1011 & ~(0111) | 0011 = 1000 | 0011 = 1011...
// Hmm. Let me reconsider.
// x OR (x+1): x's lowest 0-bit is at position k. Then x+1 = x with bit k set and bits 0..k-1 cleared.
// Since bits 0..k-1 of x are all 1, clearing and setting k gives:
// x+1 = x ^ ((1 << (k+1)) - 1)
// x OR x+1 = x | (x ^ ((1<<(k+1))-1)) = x | ((1<<(k+1))-1)
// For this to equal p, we need p = x | ((1<<(k+1))-1).
// So: bits 0..k must all be 1 in p, and x must equal p with bits 0..k cleared, plus maybe other structure.
// More precisely: x | ((1<<(k+1))-1) = p means bits 0..k are all 1 in p, and x = p & ~((1<<(k+1))-1).
// So: for each 0-bit position k in p (0-indexed), if bits 0..k-1 of p are all 1:
// x = p & ~((1<<(k+1))-1) = p with bits 0..k cleared
// To minimize x, we want to clear as many low bits as possible, so we want the highest valid k.
// Valid k: bit k of p is 0, and bits 0..k-1 of p are all 1.
// The highest such k gives the smallest x.
fn solve(p: i32) -> i32 {
if p == 2 { return -1; }
// Find the highest k such that bits 0..k of p are all 1
// x = (p & ~((1<<(k+1))-1)) | ((1<<k)-1)
// i.e. keep high bits of p, bit k = 0, bits below k = all 1
let mut best = -1i32;
for k in 0..30 {
// Check if bits 0..k of p are all 1
let mask = (1 << (k + 1)) - 1;
if p & mask == mask {
// Valid k: x = clear bits 0..k, set bits 0..k-1 to all 1
let x = (p & !(mask)) | ((1 << k) - 1);
if best == -1 || x < best {
best = x;
}
}
}
best
}
nums.iter().map(|&p| solve(p)).collect()
}
}