Given two integers a and b, find an integer x such that the number of set bits in x is equal to the number of set bits in b, and the value of (x XOR a) is minimized. Return the value of x.
Examples :
Input: a = 3, b = 5
Output: 3
Explanation: Binary representation b = 5 is 101. Since b contains 2 set bits, x must also contain exactly 2 set bits. Choosing x = 3 satisfies this condition and gives minimum XOR value as (x XOR a) becomes 0.Input: a = 7, b = 12
Output: 6
Explanation: Choosing x = 6 gives (6 XOR 7) as 1, which is the minimum possible value among all integers having exactly 2 set bits (same as b 1100).
Table of Content
[Brute Force Approach] Trying All Possible Values
- Count set bits in
b. - Iterate over all possible values of
x.Check whetherxhas the required number of set bits - Compute
(x ^ a) and store the value ofxproducing minimum XOR
#include <bits/stdc++.h>
using namespace std;
int minVal(int a, int b)
{
int bits = __builtin_popcount(b);
int res = 0;
int mini = INT_MAX;
// Find required range
int limit = max(a, b);
// Make all possible bit positions available
limit = (limit << 1) | 1;
// Try all values
for(int x = 0; x <= limit; x++)
{
// Same set bits as b
if(__builtin_popcount(x) == bits)
{
int curr = (x ^ a);
// Minimize xor value
if(curr < mini)
{
mini = curr;
res = x;
}
}
}
return res;
}
int main()
{
int a = 3, b = 5;
cout << minVal(a, b);
return 0;
}
import java.util.BitSet;
public class Main {
public static int minVal(int a, int b) {
int bits = Integer.bitCount(b);
int res = 0;
int mini = Integer.MAX_VALUE;
// Find required range
int limit = Math.max(a, b);
// Make all possible bit positions available
limit = (limit << 1) | 1;
// Try all values
for (int x = 0; x <= limit; x++) {
// Same set bits as b
if (Integer.bitCount(x) == bits) {
int curr = (x ^ a);
// Minimize xor value
if (curr < mini) {
mini = curr;
res = x;
}
}
}
return res;
}
public static void main(String[] args) {
int a = 3, b = 5;
System.out.println(minVal(a, b));
}
}
def minVal(a, b):
bits = bin(b).count('1')
res = 0
mini = float('inf')
# Find required range
limit = max(a, b)
# Make all possible bit positions available
limit = (limit << 1) | 1
# Try all values
for x in range(limit + 1):
# Same set bits as b
if bin(x).count('1') == bits:
curr = (x ^ a)
# Minimize xor value
if curr < mini:
mini = curr
res = x
return res
if __name__ == '__main__':
a = 3
b = 5
print(minVal(a, b))
using System;
class Program
{
static int minVal(int a, int b)
{
int bits = BitCount(b);
int res = 0;
int mini = int.MaxValue;
// Find required range
int limit = Math.Max(a, b);
// Make all possible bit positions available
limit = (limit << 1) | 1;
// Try all values
for (int x = 0; x <= limit; x++)
{
// Same set bits as b
if (BitCount(x) == bits)
{
int curr = (x ^ a);
// Minimize xor value
if (curr < mini)
{
mini = curr;
res = x;
}
}
}
return res;
}
static int BitCount(int n)
{
int count = 0;
while (n!= 0)
{
count += n & 1;
n >>= 1;
}
return count;
}
static void Main(string[] args)
{
int a = 3, b = 5;
Console.WriteLine(minVal(a, b));
}
}
function minVal(a, b) {
let bits = b.toString(2).split('1').length - 1;
let res = 0;
let mini = Number.MAX_SAFE_INTEGER;
// Find required range
let limit = Math.max(a, b);
// Make all possible bit positions available
limit = (limit << 1) | 1;
// Try all values
for (let x = 0; x <= limit; x++) {
// Same set bits as b
if (x.toString(2).split('1').length - 1 === bits) {
let curr = (x ^ a);
// Minimize xor value
if (curr < mini) {
mini = curr;
res = x;
}
}
}
return res;
}
let a = 3, b = 5;
console.log(minVal(a, b));
[Greedy Approach] Matching Bits to Minimize XOR – O(1) Time and O(1) Space
The idea is to construct the required number. To minimize XOR, we try to make
xas similar as possible toain binary form. Higher bits contribute more to the XOR value, so we first copy the higher set bits fromaintox. This helps keep the XOR value small. If more set bits are still needed, they are added at the lowest unset bit positions inxso that the increase in XOR remains minimum.
- Count the number of set bits in
b - Traverse bits from left to right (higher to lower). If the current bit in
ais set, set it inx andcontinue until required set bits are used - If set bits are still remaining: Traverse from lower bits to higher bits and set unset bits in
x - Return the constructed value
x
#include <bits/stdc++.h>
using namespace std;
int minVal(int a, int b) {
int bits = __builtin_popcount(b);
int x = 0;
// set matching higher bits from a
for(int i = 31; i >= 0; i--) {
if((a & (1 << i)) && bits > 0) {
x |= (1 << i);
bits--;
}
}
// set remaining lowest bits
for(int i = 0; i <= 31 && bits > 0; i++) {
if((x & (1 << i)) == 0) {
x |= (1 << i);
bits--;
}
}
return x;
}
int main() {
int a = 3, b = 5;
cout << minVal(a, b);
return 0;
}
import java.util.*;
class GFG{
public static int minVal(int a,int b){
int bits=Integer.bitCount(b);
int x=0;
// set matching higher bits from a
for(int i=31;i>=0;i--){
if((a&(1<<i))!=0 && bits>0){
x|=(1<<i);
bits--;
}
}
// set remaining lowest bits
for(int i=0;i<=31 && bits>0;i++){
if((x&(1<<i))==0){
x|=(1<<i);
bits--;
}
}
return x;
}
public static void main(String[] args){
int a=3;
int b=5;
System.out.println(minVal(a,b));
}
}
def minVal(a,b):
bits=bin(b).count('1')
x=0
# set matching higher bits from a
for i in range(31,-1,-1):
if (a&(1<<i)) and bits>0:
x|=(1<<i)
bits-=1
# set remaining lowest bits
for i in range(32):
if bits==0:
break
if (x&(1<<i))==0:
x|=(1<<i)
bits-=1
return x
a=3
b=5
print(minVal(a,b))
using System;
class GFG{
public static int countSetBits(int n){
int count=0;
while(n>0){
if((n&1)==1){
count++;
}
n=n>>1;
}
return count;
}
public static int minVal(int a,int b){
int bits=countSetBits(b);
int x=0;
// set matching higher bits from a
for(int i=31;i>=0;i--){
if((a&(1<<i))!=0 && bits>0){
x|=(1<<i);
bits--;
}
}
// set remaining lowest bits
for(int i=0;i<=31 && bits>0;i++){
if((x&(1<<i))==0){
x|=(1<<i);
bits--;
}
}
return x;
}
public static void Main(){
int a=3;
int b=5;
Console.WriteLine(minVal(a,b));
}
}
function countSetBits(n){
let count=0;
while(n>0){
if(n&1){
count++;
}
n=n>>1;
}
return count;
}
function minVal(a,b){
let bits=countSetBits(b);
let x=0;
// set matching higher bits from a
for(let i=31;i>=0;i--){
if((a&(1<<i)) && bits>0){
x|=(1<<i);
bits--;
}
}
// set remaining lowest bits
for(let i=0;i<=31 && bits>0;i++){
if((x&(1<<i))===0){
x|=(1<<i);
bits--;
}
}
return x;
}
let a=3;
let b=5;
console.log(minVal(a,b));
Output
3