A number is Sparse if there are no two adjacent 1s in its binary representation. For example 5 (binary representation: 101) is sparse, but 6 (binary representation: 110) is not sparse.
Given a number x, find the smallest Sparse number which greater than or equal to x.
Examples:
Input: x = 6
Output: Next Sparse Number is 8
Input: x = 4
Output: Next Sparse Number is 4
Input: x = 38
Output: Next Sparse Number is 40
Input: x = 44
Output: Next Sparse Number is 64
A Simple Solution is to do following:
1) Write a utility function isSparse(x) that takes a number
and returns true if x is sparse, else false. This function
can be easily written by traversing the bits of input number.
2) Start from x and do following
while(1)
{
if (isSparse(x))
return x;
else
x++
}
Time complexity of isSparse() is O(Log x). Time complexity of this solution is O(x Log x). The next sparse number can be at most O(x) distance away.
Thanks to kk_angel for suggesting above solution.
An Efficient Solution can solve this problem without checking all numbers one by one. Below are steps.
1) Find binary of the given number and store it in a
boolean array.
2) Initialize last_finalized bit position as 0.
2) Start traversing the binary from least significant bit.
a) If we get two adjacent 1's such that next (or third)
bit is not 1, then
(i) Make all bits after this 1 to last finalized
bit (including last finalized) as 0.
(ii) Update last finalized bit as next bit.
For example, let binary representation be 01010001011101, we change it to 01010001100000 (all bits after highlighted 11 are set to 0). Again two 1’s are adjacent, so change binary representation to 01010010000000. This is our final answer.
Below is the implementation of above solution.
C++
#include<bits/stdc++.h>
using namespace std;
int nextSparse( int x)
{
vector< bool > bin;
while (x != 0)
{
bin.push_back(x&1);
x >>= 1;
}
bin.push_back(0);
int n = bin.size();
int last_final = 0;
for ( int i=1; i<n-1; i++)
{
if (bin[i] == 1 && bin[i-1] == 1 && bin[i+1] != 1)
{
bin[i+1] = 1;
for ( int j=i; j>=last_final; j--)
bin[j] = 0;
last_final = i+1;
}
}
int ans = 0;
for ( int i =0; i<n; i++)
ans += bin[i]*(1<<i);
return ans;
}
int main()
{
int x = 38;
cout << "Next Sparse Number is " << nextSparse(x);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int nextSparse( int x)
{
ArrayList<Integer> bin = new ArrayList<Integer>();
while (x != 0 )
{
bin.add(x& 1 );
x >>= 1 ;
}
bin.add( 0 );
int n = bin.size();
int last_final = 0 ;
for ( int i= 1 ; i<n- 1 ; i++)
{
if (bin.get(i) == 1 && bin.get(i- 1 ) == 1 && bin.get(i+ 1 ) != 1 )
{
bin.set(i+ 1 , 1 );
for ( int j=i; j>=last_final; j--)
bin.set(j, 0 );
last_final = i+ 1 ;
}
}
int ans = 0 ;
for ( int i = 0 ; i<n; i++)
ans += bin.get(i)*( 1 <<i);
return ans;
}
public static void main(String[] args)
{
int x = 38 ;
System.out.println( "Next Sparse Number is " +nextSparse(x));
}
}
|
Python3
def nextSparse(x):
bin = []
while (x ! = 0 ):
bin .append(x & 1 )
x >> = 1
bin .append( 0 )
n = len ( bin )
last_final = 0
for i in range ( 1 ,n - 1 ):
if (( bin [i] = = 1 and bin [i - 1 ] = = 1
and bin [i + 1 ] ! = 1 )):
bin [i + 1 ] = 1
for j in range (i,last_final - 1 , - 1 ):
bin [j] = 0
last_final = i + 1
ans = 0
for i in range (n):
ans + = bin [i] * ( 1 << i)
return ans
if __name__ = = '__main__' :
x = 38
print ( "Next Sparse Number is" ,nextSparse(x))
|
C#
using System;
using System.Collections;
class GFG{
static int nextSparse( int x)
{
ArrayList bin = new ArrayList();
while (x != 0)
{
bin.Add(x&1);
x >>= 1;
}
bin.Add(0);
int n = bin.Count;
int last_final = 0;
for ( int i = 1; i < n-1; i++)
{
if (( int )bin[i] == 1 && ( int )bin[i-1] == 1 && ( int )bin[i+1] != 1)
{
bin[i+1]=1;
for ( int j = i; j >= last_final; j--)
bin[j]=0;
last_final = i + 1;
}
}
int ans = 0;
for ( int i = 0; i < n; i++)
ans += ( int )bin[i]*(1<<i);
return ans;
}
static void Main()
{
int x = 38;
Console.WriteLine( "Next Sparse Number is " +nextSparse(x));
}
}
|
PHP
<?php
function nextSparse( $x )
{
$bin = array ();
while ( $x != 0)
{
array_push ( $bin , $x & 1);
$x >>= 1;
}
array_push ( $bin , 0);
$n = count ( $bin );
$last_final = 0;
for ( $i = 1; $i < $n - 1; $i ++)
{
if ( $bin [ $i ] == 1 &&
$bin [ $i - 1] == 1 &&
$bin [ $i + 1] != 1)
{
$bin [ $i + 1] = 1;
for ( $j = $i ; $j >= $last_final ; $j --)
$bin [ $j ] = 0;
$last_final = $i + 1;
}
}
$ans = 0;
for ( $i = 0; $i < $n ; $i ++)
$ans += $bin [ $i ] * (1 << $i );
return $ans ;
}
$x = 38;
echo "Next Sparse Number is " .
nextSparse( $x );
?>
|
Javascript
<script>
function nextSparse(x)
{
let bin = new Array();
while (x != 0)
{
bin.push(x & 1);
x >>= 1;
}
bin.push(0);
n = bin.length;
let last_final = 0;
for (let i = 1; i < n - 1; i++)
{
if (bin[i] == 1 &&
bin[i - 1] == 1 &&
bin[i + 1] != 1)
{
bin[i + 1] = 1;
for (let j = i; j >= last_final; j--)
bin[j] = 0;
last_final = i + 1;
}
}
let ans = 0;
for (let i = 0; i < n; i++)
ans += bin[i] * (1 << i);
return ans;
}
let x = 38;
document.write( "Next Sparse Number is " +
nextSparse(x));
</script>
|
Output:
Next Sparse Number is 40
Time complexity of this solution is O(Log x).
Auxiliary Space: O(log x)
Thanks to gccode for suggesting above solution.
Last Updated :
10 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...