Problem
Given two positive integers num1
and num2
, find the positive integer x
such that:
x
has the same number of set bits asnum2
, 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.
Examples
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.
Constraints:
1 <= num1, num2 <= 10^9
Solution
Method 1 - Count the bits in num2 and minimize xor
Intuition
Given, num1
and num2
, we need to find a positive integer x
such that
x
has the same number of set bits asnum2
, i.e.bitCount(x)
==bitCount(num2)
x ^ num1
is minimal ⇨ set bits inx
should align with those innum1
, i.e.x
should have set bits in positions wherenum1
has1s
as well
If we XOR two bits, the result is 1 if the bits are different but 0 if the bits are the same. For example:
0 ^ 0 = 0
1 ^ 1 = 0
0 ^ 1 = 1
1 ^ 0 = 1
So, we want to minimize, hence we try to set the bits at the position, where num1
has set bits as well.
Now, there are 3 cases. Let a = bitCoun(num1)
and b = bitCount(num2)
(be number of set bits in num2
).
Cases
Case 1 - b
< a
Suppose, num2
has 3 set bits and num1
can have 5 set bits. So, in x
we want to set 3 set bits, and which one should we set? What will have more impact when we perform x ^ num1
, when we are nullifying the value, and answer is setting the bits at MSB. So, we will loop from bit position 31
to 0 for that.
Case 2 - b
> a
Suppose, num2
has 5 set bits and num1
can have 3 set bits. So, in x
we want to set 5 set bits. So, we set the 3 bits where num1
has a set bit, and now we still have 2 remaining bits we want to set in x
. Where should we set them? And the answer is since we want the minimal answer, we should set them at positions, where they contribute as minimum as possible, i.e. LSB positions, and hence we loop from bit position 0.
Case 3 - b
== a
This is the simplest case. Just set the bits as placed in num1
.
Approach
- Count Set Bits in num2: Calculate the number of set bits (1s) in
num2
and store it incnt
. We can use methods described in Number of 1 Bits or use standard library function for that. - Set Common Bits in the Result:
- To minimize
x XOR num1
, align set bits ofx
with those innum1
. Iterate from the most significant bit (MSB) to the least significant bit (LSB) ofnum1
:- If a bit in
num1
is set andcnt
is greater than 0, set the corresponding bit inx
and decrementcnt
.
- If a bit in
- To minimize
- Set Remaining Bits:
- If there are still bits left to be set in
x
(cnt > 0
), set them from LSB to MSB:- If a bit position in
num1
is not set andcnt
is greater than 0, set this bit inx
and decrementcnt
.
- If a bit position in
- If there are still bits left to be set in
Video explanation
Here is the video explaining this method in detail. Please check it out:
Code
Java
public class Solution {
public int minimizeXor(int num1, int num2) {
int cnt = Integer.bitCount(num2);
int ans = 0;
// First pass to set bits where num1 has 1s and decrease cnt
for (int i = 31; i >= 0; i--) {
if ((num1 & (1 << i)) != 0) {
if (cnt > 0) {
ans |= (1 << i);
cnt--;
}
}
}
// Second pass to set remaining bits to get required number of set bits
for (int i = 0; i < 32 && cnt > 0; i++) {
if ((num1 & (1 << i)) == 0) {
ans |= (1 << i);
cnt--;
}
}
return ans;
}
}
Python
class Solution:
def minimizeXor(self, num1: int, num2: int) -> int:
cnt = bin(num2).count('1')
ans = 0
# Set bits in ans where num1 has bits set, from MSB to LSB
for i in range(31, -1, -1):
if (num1 & (1 << i)) != 0 and cnt > 0:
ans |= (1 << i)
cnt -= 1
# Set remaining bits in ans from LSB to MSB
for i in range(32):
if cnt <= 0:
break
if (num1 & (1 << i)) == 0:
ans |= (1 << i)
cnt -= 1
return ans
Complexity
- ⏰ Time complexity:
O(1)
as we iterate through number of bits from right to left first and left to right later. ORO(log n)
if we want to right it in terms of numbers. - 🧺 Space complexity:
O(1)