Skip to main content
Back to problems
#3094
Medium Algorithms

Guess the number using bitwise questions ii

Bit Manipulation Interactive
83.1% acceptance
Apr 1, 2026
15
4

No description available.

Solution

Rust
Time O(n)
Space O(1)
LeetCode
solution.rs
impl Solution {
  unsafe fn find_number() -> i32 {
    // Each call to common_bits(num) does:
    //   count = number of bits where n and num are the same (in 30 bits)
    //   n = n XOR num
    //   return count
    //
    // To probe bit i: call common_bits(1 << i).
    // But this XORs n with (1 << i), flipping bit i.
    // To restore n, call common_bits(1 << i) again.
    //
    // If bit i of original n is 1:
    //   common_bits(1<<i) returns count where bit i matches (both 1) + other bits.
    //   Actually, count = (number of matching bit positions across all 30 bits).
    //   After first call, bit i of n is flipped to 0.
    //   Second call with same value: bit i is 0 in n and 1 in num -> mismatch, so one fewer match.
    //   But it restores n.
    //
    // Strategy: call common_bits(0) to get baseline (number of 0-bits in n in 30-bit repr).
    // baseline = number of positions where n has 0 (since 0 has all 0 bits, matching = both 0).
    // But calling common_bits(0) XORs n with 0, so n stays the same!
    // baseline = count of 0-bits in n (out of 30 bits).
    //
    // Then for each bit i: call common_bits(1 << i).
    // If bit i of n is 1: that bit now matches (both 1), but 
    //   the XOR flips bit i to 0.
    //   count_i = (zero-bits of n in other 29 positions) + 1 (bit i matches)
    //   After: n has bit i flipped. Call common_bits(1 << i) again to restore.
    // If bit i of n is 0: bit i is 0 in n and 1 in num -> mismatch.
    //   count_i = (zero-bits of n in other 29 positions) + 0
    //   After: n has bit i flipped to 1. Call again to restore.
    //
    // So: bit i is set in n iff common_bits(1<<i) > common_bits(0) - 1
    //   Actually let's think more carefully.
    //   common_bits(0) counts matching positions where both are 0 in 30 bits.
    //   = number of 0-bits in n (out of 30 bits) = 30 - popcount(n).
    //   
    //   common_bits(1<<i): counts matching positions.
    //   For bit i: matches if n's bit i == 1.
    //   For other bits j != i: matches if n's bit j == 0.
    //   = (1 if bit i set) + (29 - popcount(n with bit i masked out))
    //   
    //   If bit i is 1: = 1 + (29 - (popcount(n) - 1)) = 1 + 30 - popcount(n) = 31 - popcount(n)
    //   If bit i is 0: = 0 + (29 - popcount(n)) = 29 - popcount(n)
    //   
    //   baseline = 30 - popcount(n)
    //   If bit i is 1: count_i = 31 - popcount(n) = baseline + 1
    //   If bit i is 0: count_i = 29 - popcount(n) = baseline - 1
    //
    // So: bit i is set iff common_bits(1<<i) > baseline.
    // But we must restore n after each probe by calling common_bits(1<<i) again.
    
    let baseline = unsafe { common_bits(0) }; // n unchanged since XOR with 0
    
    let mut result = 0;
    for i in 0..30 {
      let count = unsafe { common_bits(1 << i) };
      unsafe { common_bits(1 << i) }; // restore n
      if count > baseline {
        result |= 1 << i;
      }
    }
    result
  }
}