Taro Logo

Minimize XOR

Medium
5 views
2 months ago

Given two positive integers num1 and num2, find the positive integer x such that:

  • x has the same number of set bits as num2, and
  • The value x XOR num1 is minimal.

Note that XOR is the bitwise XOR operation.

Return the integer x. The test cases are generated such that x is uniquely determined.

The number of set bits of an integer is the number of 1's in its binary representation.

Example 1:

Input: num1 = 3, num2 = 5 Output: 3 Explanation: The binary representations of num1 and num2 are 0011 and 0101, respectively. The integer 3 has the same number of set bits as num2, and the value 3 XOR 3 = 0 is minimal.

Example 2:

Input: num1 = 1, num2 = 12 Output: 3 Explanation: The binary representations of num1 and num2 are 0001 and 1100, respectively. The integer 3 has the same number of set bits as num2, and the value 3 XOR 1 = 2 is minimal.

Sample Answer
def solve():
    num1 = int(input())
    num2 = int(input())

    def count_set_bits(n):
        count = 0
        while (n > 0):
            n &= (n-1)
            count += 1
        return count

    set_bits_num2 = count_set_bits(num2)

    x = 0
    temp_num1 = num1
    
    # First, try to match the set bits in num1 from MSB to LSB.
    for i in range(31, -1, -1):
        if (temp_num1 >> i) & 1:
            if set_bits_num2 > 0:
                x |= (1 << i)
                set_bits_num2 -= 1
                
    # If we still need more set bits, add them from LSB to MSB for the unset bits.
    for i in range(32):
        if set_bits_num2 > 0 and ((num1 >> i) & 1) == 0:
            x |= (1 << i)
            set_bits_num2 -= 1
            
    # Handle the case where there are more bits in num2
    for i in range(32):
        if set_bits_num2 > 0:
           if ((x >> i) & 1) == 0:
             x |= (1 << i)
             set_bits_num2 -=1


    print(x)


# Example usage:
# num1 = 3
# num2 = 5
# The expected output is 3
# solve()

# num1 = 1
# num2 = 12
# The expected output is 3
# solve()


# A Brute force way of doing this problem will exceed time limit
# if num1 and num2 are very large numbers. You can't generate
# every possible integer and that may have bits equal to num2 because
# that will be too many possible numbers.

# Optimal way of solving this problem is trying to match
# the bits as much as possible.




Explanation:

The goal is to find an integer x such that it has the same number of set bits as num2, and x XOR num1 is minimized. Here's the approach:

  1. Count Set Bits in num2: Determine the number of set bits (1s) in the binary representation of num2. Let's call this set_bits_num2.
  2. Construct x:
    • Iterate through the bits of num1 from the most significant bit (MSB) to the least significant bit (LSB). If a bit in num1 is set (i.e., 1) and we still need more set bits in x (i.e., set_bits_num2 > 0), set the corresponding bit in x. This minimizes the XOR value because if we make a bit same as the bit in num1, their XOR will be zero, contributing to the minimal XOR sum.
    • If after the first iteration, we still need more set bits in x, then check for all unset bits in num1, set these bits one by one and subtract that from set_bits_num2 until we get the correct number of set bits in x.
    • If after the above two iterations we still require setting more bits in x, then from LSB, set the zero bits until you run out of set bits to set.

Example:

Let's trace num1 = 1 and num2 = 12.

  1. num1 in binary is 0001.
  2. num2 in binary is 1100. set_bits_num2 = 2.
  3. Iterate from MSB to LSB (31 to 0):
    • For i = 0, num1 & (1 << 0) is 1. Since set_bits_num2 > 0, set the 0th bit in x. So, x = 0001, and set_bits_num2 = 1.
    • All other bits of num1 are 0, and do not affect x.
  4. Check for unset bits of num1 and set in x, reducing set_bits_num2.
    • For i = 1, num1 & (1 << 1) == 0, thus set x to 1 << 1 = 2, x = 0011, and set_bits_num2 = 0
  5. The final value of x is 3.

Time and Space Complexity:

  • Time Complexity: O(1). The code iterates through a fixed range of bits (0 to 31). This is independent of the size of the input numbers. So the number of operations is constant.
  • Space Complexity: O(1). The code uses a fixed number of integer variables. No extra data structures are used that scale with the input size.