Find closest integer with the same weight
Last Updated :
09 Nov, 2021
Given a positive integer X the task is to find an integer Y such that:
- The count of set bits is Y is equal to the count of set bits in X.
- X != Y.
- |X – Y| is minimum.
Examples:
Input: X = 92
Output: 90
90 is the closest number to 92 having
equal number of set bits.
Input: X = 17
Output: 18
Approach: A little math can lead us to the solution approach. Since the number of bits in both the numbers has to be the same, if a set bit is flipped then an unset bit will also have to be flipped.
Now the problem reduces to choosing two bits for the flipping. Suppose one bit at index i is flipped and another bit at index j (j < i) from the LSB (least significant bit). Then the absolute value of the difference between the original integer and the new one is 2i – 2j. To minimize this, i has to be as small as possible and j has to be as close to i as possible.
Since the number of set bits have to be equal, so the bit at index i must be different from the bit at index j. This means that the smallest can be the rightmost bit that’s different from the LSB, and j must be the very next bit. In summary, the correct approach is to swap the two rightmost consecutive bits that are different.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int NumUnsignBits = 64;
unsigned long findNum(unsigned long x)
{
for ( int i = 0; i < NumUnsignBits - 1; i++) {
if (((x >> i) & 1) != ((x >> (i + 1)) & 1)) {
x ^= (1 << i) | (1 << (i + 1));
return x;
}
}
}
int main()
{
int n = 92;
cout << findNum(n);
return 0;
}
|
Java
class GFG
{
static int NumUnsignBits = 64 ;
static long findNum( long x)
{
for ( int i = 0 ; i < NumUnsignBits - 1 ; i++)
{
if (((x >> i) & 1 ) != ((x >> (i + 1 )) & 1 ))
{
x ^= ( 1 << i) | ( 1 << (i + 1 ));
return x;
}
}
return Long.MIN_VALUE;
}
public static void main(String[] args)
{
int n = 92 ;
System.out.println(findNum(n));
}
}
|
Python3
NumUnsignBits = 64 ;
def findNum(x) :
for i in range (NumUnsignBits - 1 ) :
if (((x >> i) & 1 ) ! = ((x >> (i + 1 )) & 1 )) :
x ^ = ( 1 << i) | ( 1 << (i + 1 ));
return x;
if __name__ = = "__main__" :
n = 92 ;
print (findNum(n));
|
C#
using System;
class GFG
{
static int NumUnsignBits = 64;
static long findNum( long x)
{
for ( int i = 0; i < NumUnsignBits - 1; i++)
{
if (((x >> i) & 1) != ((x >> (i + 1)) & 1))
{
x ^= (1 << i) | (1 << (i + 1));
return x;
}
}
return long .MinValue;
}
public static void Main(String[] args)
{
int n = 92;
Console.WriteLine(findNum(n));
}
}
|
Javascript
<script>
let NumUnsignBits = 64;
function findNum(x)
{
for (let i = 0; i < NumUnsignBits - 1; i++)
{
if (((x >> i) & 1) != ((x >> (i + 1)) & 1))
{
x ^= (1 << i) | (1 << (i + 1));
return x;
}
}
return Number.MIN_VALUE;
}
let n = 92;
document.write(findNum(n));
</script>
|
Time Complexity: O(logn)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...