Skip to main content
Back to problems
#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)
LeetCode
solution.rs
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()
  }
}