Generate a sequence from first X natural numbers which adds up to S on raising 2 to the power of their lowest set bits
Given two integers X and S, the task is to construct a sequence of distinct integers from the range [1, X] such that the sum of value 2K is equal to S, where K is the position of the first set bit from the end ( 0-based indexing )of the binary representation of each element is S.
Examples:
Input: X = 3, S = 4
Output: 2 3 1
Explanation:
Summation of 2K for every element in the set is as follows:
For 2, it is 2^1 = 2.
For 3, it is 2^0 = 1.
For 1, it is 2^0 = 1.
Therefore, the required sum = 2 + 1 + 1 = 4, which is equal to S.
Input: X = 1, S = 5
Output: -1
Approach: The problem can be solved using a Greedy Approach. Follow the steps below to solve the problem:
- Initialize a variable, say lowBit, to store the value of 2K for any number, where K is the position of the first set bit from the end of the binary representation of each element.
- Insert all values of lowBit for all the numbers in the range [1, X] in a vector of pairs V to pair the numbers along with their lowBit values. The value of lowBit(X) can be obtained by log2(N & -N) + 1.
- Sort the vector in the reverse order to get the maximum lowBit at first.
- Initialize an array, say ans[], to store the required set and an integer, say ansSum, to store the current summation of lowBit values.
- Traverse the vector V and perform the following steps:
- Check if (ansSum+v[i].first) <= S, then add the value of v[i].second to the array ans[] and update ansSum.
- If ansSum is equal to the given sum S, then break from the loop and print the resultant array ans[] as the result.
- If the ansSum is not found to be equal to S, then print “-1”.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int lowBit( int N)
{
return log2(N & -N) + 1;
}
void find_set( int X, int sum)
{
vector<pair< int , int > > v;
for ( int i = 1; i <= X; i++) {
pair< int , int > aux;
aux.first = lowBit(i);
aux.second = i;
v.push_back(aux);
}
sort(v.rbegin(), v.rend());
bool check = false ;
vector< int > ans;
int ansSum = 0;
for ( int i = 0; i < v.size(); i++) {
if (ansSum + v[i].first <= sum) {
ansSum += v[i].first;
ans.push_back(v[i].second);
}
if (ansSum == sum) {
check = true ;
break ;
}
}
if (!check) {
cout << "-1" ;
return ;
}
for ( int i = 0; i < ans.size(); i++) {
cout << ans[i] << " " ;
}
}
int main()
{
int X = 3, S = 4;
find_set(X, S);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class Pair {
int x;
int y;
public Pair( int x, int y)
{
this .x = x;
this .y = y;
}
}
class Compare
{
static void compare(Pair arr[], int n)
{
Arrays.sort(arr, new Comparator<Pair>() {
@Override public int compare(Pair p1, Pair p2)
{
return p1.x - p2.x;
}
});
}
}
class GFG
{
static int lowBit( int N)
{
return ( int )(Math.log(N & -N) / Math.log( 2 )) + 1 ;
}
static void find_set( int X, int sum)
{
Pair v[] = new Pair[X];
for ( int i = 0 ; i < X; i++)
{
Pair aux = new Pair(lowBit(i + 1 ), i + 1 );
v[i] = aux;
}
Compare obj = new Compare();
obj.compare(v, X);
int j = X - 1 ;
for ( int i = 0 ; i < X / 2 ; i++)
{
Pair temp = v[i];
v[i] = v[j];
v[j] = temp;
j--;
}
boolean check = false ;
Vector<Integer> ans = new Vector<Integer>();
int ansSum = 0 ;
for ( int i = 0 ; i < X; i++) {
if (ansSum + v[i].x <= sum) {
ansSum += v[i].x;
ans.add(v[i].y);
}
if (ansSum == sum) {
check = true ;
break ;
}
}
if (!check)
{
System.out.println( "-1" );
return ;
}
for ( int i = 0 ; i < ans.size(); i++)
{
System.out.print(ans.get(i) + " " );
}
}
public static void main(String[] args)
{
int X = 3 , S = 4 ;
find_set(X, S);
}
}
|
Python3
from math import log2, ceil, floor
def lowBit(N):
return log2(N & - N) + 1
def find_set(X, sum ):
v = []
for i in range ( 1 , X + 1 ):
aux = [ 0 , 0 ]
aux[ 0 ] = lowBit(i)
aux[ 1 ] = i
v.append(aux)
v = sorted (v)[:: - 1 ]
check = False
ans = []
ansSum = 0
for i in range ( len (v)):
if (ansSum + v[i][ 0 ] < = sum ):
ansSum + = v[i][ 0 ]
ans.append(v[i][ 1 ])
if (ansSum = = sum ):
check = True
break
if ( not check):
print ( "-1" )
return
for i in range ( len (ans)):
print (ans[i], end = " " )
if __name__ = = '__main__' :
X, S = 3 , 4
find_set(X, S)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int lowBit( int N)
{
return ( int )(Math.Log(N & -N, 2)) + 1;
}
static void find_set( int X, int sum)
{
List<Tuple< int , int >> v = new List<Tuple< int , int >>();
for ( int i = 1; i <= X; i++) {
Tuple< int , int > aux = new Tuple< int , int >(lowBit(i), i);
v.Add(aux);
}
v.Sort();
v.Reverse();
bool check = false ;
List< int > ans = new List< int >();
int ansSum = 0;
for ( int i = 0; i < v.Count; i++) {
if (ansSum + v[i].Item1 <= sum) {
ansSum += v[i].Item1;
ans.Add(v[i].Item2);
}
if (ansSum == sum) {
check = true ;
break ;
}
}
if (!check) {
Console.Write( "-1" );
return ;
}
for ( int i = 0; i < ans.Count; i++) {
Console.Write(ans[i] + " " );
}
}
static void Main()
{
int X = 3, S = 4;
find_set(X, S);
}
}
|
Javascript
<script>
function lowBit(N) {
return Math.log2(N & -N) + 1;
}
function find_set(X, sum) {
let v = [];
for (let i = 1; i <= X; i++) {
let aux = [];
aux[0] = lowBit(i);
aux[1] = i;
v.push(aux);
}
v.sort((a, b) => a[0] - b[0]).reverse();
let check = false ;
let ans = [];
let ansSum = 0;
for (let i = 0; i < v.length; i++) {
if (ansSum + v[i][0] <= sum) {
ansSum += v[i][0];
ans.push(v[i][1]);
}
if (ansSum == sum) {
check = true ;
break ;
}
}
if (!check) {
document.write( "-1" );
return ;
}
for (let i = 0; i < ans.length; i++) {
document.write(ans[i] + " " );
}
}
let X = 3, S = 4;
find_set(X, S);
</script>
|
Time Complexity: O(X Log X) because we need to calculate the lowest set bit for all integers from 1 to X, and sorting the vector of pairs takes O(X log X) time.
Auxiliary Space: O(X)
Last Updated :
20 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...