Given a positive integer n, generate all n-bit binary numbers such that, for every prefix of each binary number, the count of 1's is greater than or equal to the count of 0's.
Return the binary numbers in decreasing order of their decimal value.
Examples:
Input: n = 2
Output: ["11", "10"]
Explanation: Valid numbers are those where each prefix has more 1s than 0s:
11: all its prefixes (1 and 11) have more 1s than 0s.
10: all its prefixes (1 and 10) have more 1s than 0s.
So, the output is "11, 10".Input: n = 3
Output: ["111", "110", "101"]
Explanation: Valid numbers are those where each prefix has more 1s than 0s.
111: all its prefixes (1, 11, and 111) have more 1s than 0s.
110: all its prefixes (1, 11, and 110) have more 1s than 0s.
101: all its prefixes (1, 10, and 101) have more 1s than 0s.
So, the output is "111, 110, 101".
Table of Content
[Naive Approach] Generate All and Check Prefixes - O(n * 2 ^ n) Time and O(n * 2 ^ n) Space
The idea is to generate all possible n-bit binary numbers and check whether every prefix has at least as many 1s as 0s.
Working of Approach:
- Generate all possible binary strings of length n.
- For every complete binary string, traverse it from left to right.
- Count the number of 1s and 0s in every prefix.
- If 0s become greater than 1s, discard the string.
- Otherwise, add the valid string to the answer.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Function to check whether all prefixes are valid
bool isValid(string &number)
{
int ones = 0;
int zeros = 0;
// Traverse the binary number
for (char ch : number)
{
if (ch == '1')
ones++;
else
zeros++;
// If zeros become greater than ones, return false
if (zeros > ones)
return false;
}
return true;
}
// Recursive function to generate all binary strings
void generate(string number, int remainingPlaces, vector<string> &res)
{
// Base case: All places have been filled
if (remainingPlaces == 0)
{
// Add the number only if all prefixes are valid
if (isValid(number))
res.push_back(number);
return;
}
// Add 1 first to maintain decreasing order
generate(number + "1", remainingPlaces - 1, res);
// Add 0
generate(number + "0", remainingPlaces - 1, res);
}
vector<string> nBitBinary(int n)
{
vector<string> res;
// Generate all possible n-bit binary numbers
generate("", n, res);
return res;
}
int main()
{
int n = 3;
vector<string> ans = nBitBinary(n);
cout << "[";
for (int i = 0; i < ans.size(); i++)
{
cout << "\"" << ans[i] << "\"";
if (i + 1 < ans.size())
cout << ", ";
}
cout << "]";
return 0;
}
import java.util.ArrayList;
class GFG {
// Function to check whether all prefixes are valid
static boolean isValid(String number)
{
int ones = 0;
int zeros = 0;
// Traverse the binary number
for (char ch : number.toCharArray()) {
if (ch == '1')
ones++;
else
zeros++;
// If zeros become greater than ones, return
// false
if (zeros > ones)
return false;
}
return true;
}
// Recursive function to generate all binary strings
static void generate(String number, int remainingPlaces,
ArrayList<String> res)
{
// Base case: All places have been filled
if (remainingPlaces == 0) {
// Add the number only if all prefixes are valid
if (isValid(number))
res.add(number);
return;
}
// Add 1 first to maintain decreasing order
generate(number + "1", remainingPlaces - 1, res);
// Add 0
generate(number + "0", remainingPlaces - 1, res);
}
static ArrayList<String> nBitBinary(int n)
{
ArrayList<String> res = new ArrayList<>();
// Generate all possible n-bit binary numbers
generate("", n, res);
return res;
}
public static void main(String[] args)
{
int n = 3;
ArrayList<String> ans = nBitBinary(n);
System.out.print("[");
for (int i = 0; i < ans.size(); i++) {
System.out.print("\"" + ans.get(i) + "\"");
if (i + 1 < ans.size())
System.out.print(", ");
}
System.out.print("]");
}
}
"""
Function to check whether all prefixes are valid
"""
def isValid(number):
ones = 0
zeros = 0
# Traverse the binary number
for ch in number:
if ch == '1':
ones += 1
else:
zeros += 1
# If zeros become greater than ones, return false
if zeros > ones:
return False
return True
# Recursive function to generate all binary strings
def generate(number, remainingPlaces, res):
# Base case: All places have been filled
if remainingPlaces == 0:
# Add the number only if all prefixes are valid
if isValid(number):
res.append(number)
return
# Add 1 first to maintain decreasing order
generate(number + '1', remainingPlaces - 1, res)
# Add 0
generate(number + '0', remainingPlaces - 1, res)
def nBitBinary(n):
res = []
# Generate all possible n-bit binary numbers
generate('', n, res)
return res
if __name__ == '__main__':
n = 3
ans = nBitBinary(n)
print('[')
for i in range(len(ans)):
print(f'"{ans[i]}"', end='')
if i + 1 < len(ans):
print(', ', end='')
print(']')
using System;
using System.Collections.Generic;
class GFG {
// Function to check whether all prefixes are valid
static bool isValid(string number)
{
int ones = 0;
int zeros = 0;
// Traverse the binary number
foreach(char ch in number)
{
if (ch == '1')
ones++;
else
zeros++;
// If zeros become greater than ones, return
// false
if (zeros > ones)
return false;
}
return true;
}
// Recursive function to generate all binary strings
static void generate(string number, int remainingPlaces,
List<string> res)
{
// Base case: All places have been filled
if (remainingPlaces == 0) {
// Add the number only if all prefixes are valid
if (isValid(number))
res.Add(number);
return;
}
// Add 1 first to maintain decreasing order
generate(number + "1", remainingPlaces - 1, res);
// Add 0
generate(number + "0", remainingPlaces - 1, res);
}
static List<string> nBitBinary(int n)
{
List<string> res = new List<string>();
// Generate all possible n-bit binary numbers
generate("", n, res);
return res;
}
public static void Main(string[] args)
{
int n = 3;
List<string> ans = nBitBinary(n);
Console.Write("[");
for (int i = 0; i < ans.Count; i++) {
Console.Write("\"" + ans[i] + "\"");
if (i + 1 < ans.Count)
Console.Write(", ");
}
Console.Write("]");
}
}
/*
Function to check whether all prefixes are valid
*/
function isValid(number)
{
let ones = 0;
let zeros = 0;
// Traverse the binary number
for (let ch of number) {
if (ch === "1") {
ones++;
}
else {
zeros++;
}
// If zeros become greater than ones, return false
if (zeros > ones) {
return false;
}
}
return true;
}
/*
Recursive function to generate all binary strings
*/
function generate(number, remainingPlaces, res)
{
// Base case: All places have been filled
if (remainingPlaces === 0) {
// Add the number only if all prefixes are valid
if (isValid(number)) {
res.push(number);
}
return;
}
// Add 1 first to maintain decreasing order
generate(number + "1", remainingPlaces - 1, res);
// Add 0
generate(number + "0", remainingPlaces - 1, res);
}
function nBitBinary(n)
{
let res = [];
// Generate all possible n-bit binary numbers
generate("", n, res);
return res;
}
// Driver Code
let n = 3;
let ans = nBitBinary(n);
console.log("[");
for (let i = 0; i < ans.length; i++) {
console.log(`\"${ans[i]}\"`);
if (i + 1 < ans.length) {
console.log(", ");
}
}
console.log("]");
Output
["111", "110", "101"]
[Expected Approach] Generate Valid Using Backtracking - O(2 ^ n) Time and O(n * 2 ^ n) Space
The idea is to recursively build only valid binary numbers by adding '0' only when the number of 1s is greater than the number of 0s.
Working of Approach:
- Start with an empty binary string and extraOnes = 0.
- Always add '1', which increases extraOnes by 1.
- Add '0' only when extraOnes > 0.
- Adding '0' decreases extraOnes by 1.
- When all n positions are filled, add the binary number to the answer.
Let us understand with an example:
Input: n = 3
- Start with an empty string "", extraOnes = 0, and remainingPlaces = 3.
- Add '1' first, giving "1" with extraOnes = 1.
- Continue adding '1' and '0' recursively, but add '0' only when extraOnes > 0.
- The valid 3-bit binary numbers generated are "111", "110", and "101".
- When remainingPlaces becomes 0, add the generated binary number to the answer.
Final Output: ["111", "110", "101"]
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Recursive utility function to generate N-bit binary
// numbers with specified number of ones
void nBitBinaryUtil(string number, int extraOnes,
int remainingPlaces, vector<string> &ans)
{
// Base case: If all places have been filled, add the
// number to the answer vector and return
if (remainingPlaces == 0)
{
ans.push_back(number);
return;
}
// Recursive call to add a '1' to the current number
// and update the count of extra ones and remaining
// places
nBitBinaryUtil(number + "1", extraOnes + 1,
remainingPlaces - 1, ans);
// Check if there are any extra ones that can
// be used to add a '0'
if (extraOnes > 0)
nBitBinaryUtil(number + "0", extraOnes - 1,
remainingPlaces - 1, ans);
}
vector<string> nBitBinary(int n)
{
vector<string> res;
string s = "";
// Call the utility function to recursively
// generate the N-bit binary numbers
nBitBinaryUtil(s, 0, n, res);
return res;
}
int main()
{
int n = 3;
vector<string> ans = nBitBinary(n);
cout << "[";
for (int i = 0; i < ans.size(); i++)
{
cout << "\"" << ans[i] << "\"";
if (i + 1 < ans.size())
cout << ", ";
}
cout << "]";
return 0;
}
import java.util.ArrayList;
class GFG {
// Recursive utility function to generate N-bit binary
// numbers with specified number of ones
static void nBitBinaryUtil(String number, int extraOnes,
int remainingPlaces,
ArrayList<String> ans)
{
// Base case: If all places have been filled, add
// the number to the answer list and return
if (remainingPlaces == 0) {
ans.add(number);
return;
}
// Recursive call to add a '1' to the current number
// and update the count of extra ones and remaining
// places
nBitBinaryUtil(number + "1", extraOnes + 1,
remainingPlaces - 1, ans);
// Check if there are any extra ones that can be
// used to add a '0'
if (0 < extraOnes)
nBitBinaryUtil(number + "0", extraOnes - 1,
remainingPlaces - 1, ans);
}
static ArrayList<String> nBitBinary(int n)
{
ArrayList<String> res = new ArrayList<>();
String s = "";
// Call the utility function to recursively generate
// the N-bit binary numbers
nBitBinaryUtil(s, 0, n, res);
return res;
}
public static void main(String[] args)
{
int n = 3;
ArrayList<String> ans = nBitBinary(n);
System.out.print("[");
for (int i = 0; i < ans.size(); i++) {
System.out.print("\"" + ans.get(i) + "\"");
if (i + 1 < ans.size())
System.out.print(", ");
}
System.out.print("]");
}
}
def nBitBinaryUtil(number, extraOnes, remainingPlaces, ans):
# Base case: If all places have been filled, add
# the number to the answer vector and return
if remainingPlaces == 0:
ans.append(number)
return
# Recursive call to add a '1' to the current number
# and update the count of extra ones and remaining
# places
nBitBinaryUtil(number + '1', extraOnes + 1, remainingPlaces - 1, ans)
# Check if there are any extra ones that can be used to add a '0'
if extraOnes > 0:
nBitBinaryUtil(number + '0', extraOnes - 1, remainingPlaces - 1, ans)
def nBitBinary(n):
res = []
s = ''
# Call the utility function to recursively
# generate the N-bit binary numbers
nBitBinaryUtil(s, 0, n, res)
return res
if __name__ == '__main__':
n = 3
ans = nBitBinary(n)
print('[', end='')
for i in range(len(ans)):
print(f'"{ans[i]}"', end='')
if i + 1 < len(ans):
print(', ', end='')
print(']')
using System;
using System.Collections.Generic;
class GFG {
// Recursive utility function to generate N-bit binary
// numbers with specified number of ones
static void nBitBinaryUtil(string number, int extraOnes,
int remainingPlaces,
List<string> ans)
{
// Base case: If all places have been filled, add
// the number to the answer list and return
if (remainingPlaces == 0) {
ans.Add(number);
return;
}
// Recursive call to add a '1' to the current number
// and update the count of extra ones and remaining
// places
nBitBinaryUtil(number + "1", extraOnes + 1,
remainingPlaces - 1, ans);
// Check if there are any extra ones that can be
// used to add a '0'
if (0 < extraOnes)
nBitBinaryUtil(number + "0", extraOnes - 1,
remainingPlaces - 1, ans);
}
static List<string> nBitBinary(int n)
{
List<string> res = new List<string>();
string s = "";
// Call the utility function to recursively generate
// the N-bit binary numbers
nBitBinaryUtil(s, 0, n, res);
return res;
}
public static void Main(string[] args)
{
int n = 3;
List<string> ans = nBitBinary(n);
Console.Write("[");
for (int i = 0; i < ans.Count; i++) {
Console.Write("\"" + ans[i] + "\"");
if (i + 1 < ans.Count)
Console.Write(", ");
}
Console.Write("]");
}
}
function nBitBinaryUtil(number, extraOnes, remainingPlaces,
ans)
{
// Base case: If all places have been filled, add the
// number to the answer vector and return
if (remainingPlaces === 0) {
ans.push(number);
return;
}
// Recursive call to add a '1' to the current number and
// update the count of extra ones and remaining places
nBitBinaryUtil(number + "1", extraOnes + 1,
remainingPlaces - 1, ans);
// Check if there are any extra ones that can be used to
// add a '0'
if (extraOnes > 0)
nBitBinaryUtil(number + "0", extraOnes - 1,
remainingPlaces - 1, ans);
}
function nBitBinary(n)
{
let res = [];
let s = "";
// Call the utility function to recursively generate the
// N-bit binary numbers
nBitBinaryUtil(s, 0, n, res);
return res;
}
// Driver Code
let n = 3;
let ans = nBitBinary(n);
console.log("[");
for (let i = 0; i < ans.length; i++) {
process.stdout.write(`\"${ans[i]}\"`);
if (i + 1 < ans.length)
process.stdout.write(", ");
}
console.log("]");
Output
["111", "110", "101"]