Given a number k, find all the possible combinations of k-bit numbers with n-bits set where 1 <= n <= k. The solution should print all numbers with one set bit first, followed by numbers with two bits set,.. up to the numbers whose all k-bits are set. If two numbers have the same number of set bits, then smaller number should come first. Examples:
Input: K = 3
Output:
001 010 100
011 101 110
111
Input: K = 4
Output:
0001 0010 0100 1000
0011 0101 0110 1001 1010 1100
0111 1011 1101 1110
1111
Input: K = 5
Output:
00001 00010 00100 01000 10000
00011 00101 00110 01001 01010 01100 10001 10010 10100 11000
00111 01011 01101 01110 10011 10101 10110 11001 11010 11100
01111 10111 11011 11101 11110
11111
We need to find all the possible combinations of k-bit numbers with n set bits where 1 <= n <= k. If we carefully analyze, we see that problem can further be divided into sub-problems. We can find all combinations of length k with n ones by prefixing 0 to all combinations of length k-1 with n ones and 1 to all combinations of length k-1 with n-1 ones. We can use Dynamic Programming to save solutions of sub-problems. Below is C++ implementation of above idea –
C++
#include <iostream>
#include <vector>
using namespace std;
#define K 16
vector<string> DP[K][K];
void findBitCombinations( int k)
{
string str = "" ;
for ( int len = 0; len <= k; len++)
{
DP[len][0].push_back(str);
str = str + "0" ;
}
for ( int len = 1; len <= k; len++)
{
for ( int n = 1; n <= len; n++)
{
for (string str : DP[len - 1][n])
DP[len][n].push_back( "0" + str);
for (string str : DP[len - 1][n - 1])
DP[len][n].push_back( "1" + str);
}
}
for ( int n = 1; n <= k; n++)
{
for (string str : DP[k][n])
cout << str << " " ;
cout << endl;
}
}
int main()
{
int k = 5;
for ( int i=0;i<k;i++)
cout<< "0" ;
cout<<endl;
findBitCombinations(k);
return 0;
}
|
Java
import java.util.ArrayList;
public class BitCombinations
{
public static void findBitCombinations( int k)
{
ArrayList<ArrayList<String>> combinations = new ArrayList<>();
for ( int n = 1 ; n <= k; n++) {
ArrayList<String> currentCombination = new ArrayList<>();
for ( int i = 0 ; i < Math.pow( 2 , k); i++)
{
String binaryString = Integer.toBinaryString(i);
if ((binaryString.length() - binaryString.replace( "1" , "" ).length()) == n) {
currentCombination.add(String.format( "%0" + k + "d" , Long.parseLong(binaryString)));
}
}
combinations.add(currentCombination);
}
System.out.println( "00000" );
for ( int i = 0 ; i < combinations.size(); i++) {
System.out.println(String.join( " " , combinations.get(i)));
}
}
public static void main(String[] args) {
int k = 5 ;
findBitCombinations(k);
}
}
|
Python3
K = 16
DP = [[[] for _ in range (K)] for _ in range (K)]
def findBitCombinations(k):
global DP
str = ""
for len in range (k + 1 ):
DP[ len ][ 0 ].append( str )
str + = "0"
for len in range ( 1 , k + 1 ):
for n in range ( 1 , len + 1 ):
for str in DP[ len - 1 ][n]:
DP[ len ][n].append( "0" + str )
for str in DP[ len - 1 ][n - 1 ]:
DP[ len ][n].append( "1" + str )
for n in range (k + 1 ):
for str in DP[k][n]:
print ( str , end = " " )
print ()
k = 5
findBitCombinations(k)
|
C#
using System;
using System.Collections.Generic;
public class BitCombinations
{
public static void findBitCombinations( int k)
{
List<List< string >> combinations = new List<List< string >>();
for ( int n = 1; n <= k; n++) {
List< string > currentCombination = new List< string >();
for ( int i = 0; i < Math.Pow(2, k); i++) {
string binaryString = Convert.ToString(i, 2).PadLeft(k, '0' );
if ((binaryString.Length - binaryString.Replace( "1" , "" ).Length) == n) {
currentCombination.Add(binaryString);
}
}
combinations.Add(currentCombination);
}
Console.WriteLine( "00000" );
foreach (List< string > combination in combinations) {
Console.WriteLine( string .Join( " " , combination));
}
}
public static void Main( string [] args)
{
int k = 5;
findBitCombinations(k);
}
}
|
Javascript
function findBitCombinations(k) {
const combinations = [];
for (let n = 1; n <= k; n++) {
const currentCombination = [];
for (let i = 0; i < Math.pow(2, k); i++) {
const binaryString = (i).toString(2);
if ((binaryString.match(/1/g) || []).length === n) {
currentCombination.push(binaryString.padStart(k, '0' ));
}
}
combinations.push(currentCombination);
}
let curr= ''
for (let i=0;i<k;i++)
curr=curr+ '0'
console.log(curr)
for (let i = 0; i < combinations.length; i++) {
console.log(combinations[i].join( ' ' ));
console.log();
}
}
const k = 5;
findBitCombinations(k);
|
Output
00000
00001 00010 00100 01000 10000
00011 00101 00110 01001 01010 01100 10001 10010 10100 11000
00111 01011 01101 01110 10011 10101 10110 11001 11010 11100
01111 10111 11011 11101 11110
11111
This article is contributed by Aditya Goel. If you like neveropen and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the neveropen main page and help other Geeks. Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!