Count number of binary strings without consecutive 1’s : Set 2
Last Updated :
20 Oct, 2023
Given a positive integer N, the task is to count all possible distinct binary strings of length N such that there are no consecutive 1’s.
Examples:
Input: N = 5
Output: 5
Explanation:
The non-negative integers <= 5 with their corresponding binary representations are:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only 3 has two consecutive 1's. Therefore required count = 5
Input: N = 12
Output: 8
Dynamic Programming Approach: A dynamic programming approach has already been discussed in this article.
Approach: In this article, an approach using the concept of digit-dp is discussed.
- Similar to the digit-dp problem, a 3-dimensional table is created here to store the computed values. It is assumed that the N < 231 - 1, and the range of every number is only 2 (Either 0 or 1). Therefore, the dimensions of the table are taken as 32 x 2 x 2.
- After constructing the table, the given number is converted to a binary string.
- Then, the number is iterated. For every iteration:
- Check if the previous digit is a 0 or 1.
- If it is a 0, then the present number can either be a 0 or 1.
- But if the previous number is 1, then the present number has to be 0 because we can't have two consecutive 1's in the binary representation.
- Now, the table is exactly filled like the digit-dp problem.
Below is the implementation of the above approach
C++
// C++ program to count number of
// binary strings without consecutive 1’s
#include <bits/stdc++.h>
using namespace std;
// Table to store the solution of
// every sub problem
int memo[32][2][2];
// Function to fill the table
/* Here,
pos: keeps track of current position.
f1: is the flag to check if current
number is less than N or not.
pr: represents the previous digit
*/
int dp(int pos, int fl, int pr, string& bin)
{
// Base case
if (pos == bin.length())
return 1;
// Check if this subproblem
// has already been solved
if (memo[pos][fl][pr] != -1)
return memo[pos][fl][pr];
int val = 0;
// Placing 0 at the current position
// as it does not violate the condition
if (bin[pos] == '0')
val = val + dp(pos + 1, fl, 0, bin);
// Here flag will be 1 for the
// next recursive call
else if (bin[pos] == '1')
val = val + dp(pos + 1, 1, 0, bin);
// Placing 1 at this position only if
// the previously inserted number is 0
if (pr == 0) {
// If the number is smaller than N
if (fl == 1) {
val += dp(pos + 1, fl, 1, bin);
}
// If the digit at current position is 1
else if (bin[pos] == '1') {
val += dp(pos + 1, fl, 1, bin);
}
}
// Storing the solution to this subproblem
return memo[pos][fl][pr] = val;
}
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
int findIntegers(int num)
{
// Convert N to binary form
string bin;
// Loop to convert N
// from Decimal to binary
while (num > 0) {
if (num % 2)
bin += "1";
else
bin += "0";
num /= 2;
}
reverse(bin.begin(), bin.end());
// Initialising the table with -1.
memset(memo, -1, sizeof(memo));
// Calling the function
return dp(0, 0, 0, bin);
}
// Driver code
int main()
{
int N = 12;
cout << findIntegers(N);
return 0;
}
Java
// Java program to count number of
// binary Strings without consecutive 1’s
import java.io.*;
class GFG{
// Table to store the solution of
// every sub problem
static int [][][]memo = new int[32][2][2];
// Function to fill the table
/* Here,
pos: keeps track of current position.
f1: is the flag to check if current
number is less than N or not.
pr: represents the previous digit
*/
static int dp(int pos, int fl, int pr, String bin)
{
// Base case
if (pos == bin.length())
return 1;
// Check if this subproblem
// has already been solved
if (memo[pos][fl][pr] != -1)
return memo[pos][fl][pr];
int val = 0;
// Placing 0 at the current position
// as it does not violate the condition
if (bin.charAt(pos) == '0')
val = val + dp(pos + 1, fl, 0, bin);
// Here flag will be 1 for the
// next recursive call
else if (bin.charAt(pos) == '1')
val = val + dp(pos + 1, 1, 0, bin);
// Placing 1 at this position only if
// the previously inserted number is 0
if (pr == 0) {
// If the number is smaller than N
if (fl == 1) {
val += dp(pos + 1, fl, 1, bin);
}
// If the digit at current position is 1
else if (bin.charAt(pos) == '1') {
val += dp(pos + 1, fl, 1, bin);
}
}
// Storing the solution to this subproblem
return memo[pos][fl][pr] = val;
}
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
static int findIntegers(int num)
{
// Convert N to binary form
String bin = "";
// Loop to convert N
// from Decimal to binary
while (num > 0) {
if (num % 2 == 1)
bin += "1";
else
bin += "0";
num /= 2;
}
bin = reverse(bin);
// Initialising the table with -1.
for(int i = 0; i < 32; i++){
for(int j = 0; j < 2; j++){
for(int l = 0; l < 2; l++)
memo[i][j][l] = -1;
}
}
// Calling the function
return dp(0, 0, 0, bin);
}
static String reverse(String input) {
char[] a = input.toCharArray();
int l, r = a.length - 1;
for (l = 0; l < r; l++, r--) {
char temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return String.valueOf(a);
}
// Driver code
public static void main(String[] args)
{
int N = 12;
System.out.print(findIntegers(N));
}
}
// This code is contributed by sapnasingh4991
Python3
# Python program to count number of
# binary strings without consecutive 1’s
# Table to store the solution of
# every sub problem
memo=[[[-1 for i in range(2)] for j in range(2)] for k in range(32)]
# Function to fill the table
''' Here,
pos: keeps track of current position.
f1: is the flag to check if current
number is less than N or not.
pr: represents the previous digit
'''
def dp(pos,fl,pr,bin):
# Base case
if (pos == len(bin)):
return 1;
# Check if this subproblem
# has already been solved
if (memo[pos][fl][pr] != -1):
return memo[pos][fl][pr];
val = 0
# Placing 0 at the current position
# as it does not violate the condition
if (bin[pos] == '0'):
val = val + dp(pos + 1, fl, 0, bin)
# Here flag will be 1 for the
# next recursive call
elif (bin[pos] == '1'):
val = val + dp(pos + 1, 1, 0, bin)
# Placing 1 at this position only if
# the previously inserted number is 0
if (pr == 0):
# If the number is smaller than N
if (fl == 1):
val += dp(pos + 1, fl, 1, bin)
# If the digit at current position is 1
elif (bin[pos] == '1'):
val += dp(pos + 1, fl, 1, bin)
# Storing the solution to this subproblem
memo[pos][fl][pr] = val
return val
# Function to find the number of integers
# less than or equal to N with no
# consecutive 1’s in binary representation
def findIntegers(num):
# Convert N to binary form
bin=""
# Loop to convert N
# from Decimal to binary
while (num > 0):
if (num % 2):
bin += "1"
else:
bin += "0"
num //= 2
bin=bin[::-1];
# Calling the function
return dp(0, 0, 0, bin)
# Driver code
if __name__ == "__main__":
N = 12
print(findIntegers(N))
C#
// C# program to count number of
// binary Strings without consecutive 1’s
using System;
public class GFG{
// Table to store the solution of
// every sub problem
static int [,,]memo = new int[32,2,2];
// Function to fill the table
/* Here,
pos: keeps track of current position.
f1: is the flag to check if current
number is less than N or not.
pr: represents the previous digit
*/
static int dp(int pos, int fl, int pr, String bin)
{
// Base case
if (pos == bin.Length)
return 1;
// Check if this subproblem
// has already been solved
if (memo[pos,fl,pr] != -1)
return memo[pos,fl,pr];
int val = 0;
// Placing 0 at the current position
// as it does not violate the condition
if (bin[pos] == '0')
val = val + dp(pos + 1, fl, 0, bin);
// Here flag will be 1 for the
// next recursive call
else if (bin[pos] == '1')
val = val + dp(pos + 1, 1, 0, bin);
// Placing 1 at this position only if
// the previously inserted number is 0
if (pr == 0) {
// If the number is smaller than N
if (fl == 1) {
val += dp(pos + 1, fl, 1, bin);
}
// If the digit at current position is 1
else if (bin[pos] == '1') {
val += dp(pos + 1, fl, 1, bin);
}
}
// Storing the solution to this subproblem
return memo[pos,fl,pr] = val;
}
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
static int findints(int num)
{
// Convert N to binary form
String bin = "";
// Loop to convert N
// from Decimal to binary
while (num > 0) {
if (num % 2 == 1)
bin += "1";
else
bin += "0";
num /= 2;
}
bin = reverse(bin);
// Initialising the table with -1.
for(int i = 0; i < 32; i++){
for(int j = 0; j < 2; j++){
for(int l = 0; l < 2; l++)
memo[i,j,l] = -1;
}
}
// Calling the function
return dp(0, 0, 0, bin);
}
static String reverse(String input) {
char[] a = input.ToCharArray();
int l, r = a.Length - 1;
for (l = 0; l < r; l++, r--) {
char temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return String.Join("",a);
}
// Driver code
public static void Main(String[] args)
{
int N = 12;
Console.Write(findints(N));
}
}
// This code contributed by Rajput-Ji
JavaScript
<script>
// JavaScript program to count number of
// binary strings without consecutive 1’s
// Table to store the solution of
// every sub problem
var memo = Array.from(Array(32), ()=>Array(2));
for(var i =0;i<32;i++)
{
for(var j =0; j<2; j++)
{
memo[i][j] = new Array(2).fill(-1);
}
}
// Function to fill the table
/* Here,
pos: keeps track of current position.
f1: is the flag to check if current
number is less than N or not.
pr: represents the previous digit
*/
function dp(pos, fl, pr, bin)
{
// Base case
if (pos == bin.length)
return 1;
// Check if this subproblem
// has already been solved
if (memo[pos][fl][pr] != -1)
return memo[pos][fl][pr];
var val = 0;
// Placing 0 at the current position
// as it does not violate the condition
if (bin[pos] == '0')
val = val + dp(pos + 1, fl, 0, bin);
// Here flag will be 1 for the
// next recursive call
else if (bin[pos] == '1')
val = val + dp(pos + 1, 1, 0, bin);
// Placing 1 at this position only if
// the previously inserted number is 0
if (pr == 0) {
// If the number is smaller than N
if (fl == 1) {
val += dp(pos + 1, fl, 1, bin);
}
// If the digit at current position is 1
else if (bin[pos] == '1') {
val += dp(pos + 1, fl, 1, bin);
}
}
// Storing the solution to this subproblem
return memo[pos][fl][pr] = val;
}
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
function findIntegers(num)
{
// Convert N to binary form
var bin = "";
// Loop to convert N
// from Decimal to binary
while (num > 0) {
if (num % 2)
bin += "1";
else
bin += "0";
num =parseInt(num/2);
}
bin = bin.split('').reverse().join('')
// Calling the function
return dp(0, 0, 0, bin);
}
// Driver code
var N = 12;
document.write( findIntegers(N));
</script>
Time Complexity: O(L * log(N))
- O(log(N)) to convert the number from Decimal to binary.
- O(L) to fill the table, where L is the length of the binary form.
Auxiliary Space: O(32 * 2 * 2)
Efficient approach : DP tabulation (iterative)
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls. In this approach we use 3D DP store computation of subproblems and find the final result using iteration and not with the help of recursion.
Implementation Steps:
- Convert the given number N to its binary representation.
- Initialize a DP table of size n+1 x 2 x 2, where n is the number of digits in the binary representation of N.
- Loop through each digit of the binary representation of N and fill the DP table using the recurrence relation: dp[i][j | (l < limit)][l] += dp[i-1][j][k], where dp[i][j][k] represents the number of binary strings of length i that do not have consecutive 1s, and j and k represent whether the previous digit and current digit are both 1s, respectively.
- Sum up the number of valid binary strings of length N by adding dp[n][i][0] and dp[n][i][1] for i = 0 to 1.
- Return the final count of valid binary strings.
Implementation:
C++
// C++ program to count number of
// binary strings without consecutive 1’s
#include <bits/stdc++.h>
using namespace std;
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
int findIntegers(int num)
{
// Convert N to binary form
string bin;
// Loop to convert N
// from Decimal to binary
while (num > 0) {
if (num % 2)
bin += "1";
else
bin += "0";
num /= 2;
}
reverse(bin.begin(), bin.end());
int n = bin.length();
// DP table to store the solutions
int dp[n + 1][2][2];
memset(dp, 0, sizeof(dp));
// Initializing the DP table
dp[0][0][0] = 1;
// Loop through each digit
for (int i = 1; i <= n; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
int limit = (j ? 1 : bin[i - 1] - '0');
for (int l = 0; l <= limit; l++) {
if (l == 1 && k == 1)
continue;
dp[i][j | (l < limit)][l] += dp[i - 1][j][k];
}
}
}
}
// Calculating the result
int result = 0;
for (int i = 0; i < 2; i++) {
result += dp[n][i][0];
result += dp[n][i][1];
}
// return the final answer
return result;
}
// Driver code
int main()
{
int N = 12;
cout << findIntegers(N);
return 0;
}
Java
// Java code for above approach
import java.util.Arrays;
public class Main {
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
static int findIntegers(int num) {
// Convert N to binary form
StringBuilder bin = new StringBuilder();
// Loop to convert N
// from Decimal to binary
while (num > 0) {
if (num % 2 == 1)
bin.append("1");
else
bin.append("0");
num /= 2;
}
bin.reverse();
int n = bin.length();
// DP table to store the solutions
int[][][] dp = new int[n + 1][2][2];
for (int[][] arr : dp) {
for (int[] subArr : arr) {
Arrays.fill(subArr, 0);
}
}
// Initializing the DP table
dp[0][0][0] = 1;
// Loop through each digit
for (int i = 1; i <= n; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
int limit = (j == 1) ? 1 : (bin.charAt(i - 1) - '0');
for (int l = 0; l <= limit; l++) {
if (l == 1 && k == 1)
continue;
dp[i][j | ((l < limit) ? 1 : 0)][l] += dp[i - 1][j][k];
}
}
}
}
// Calculating the result
int result = 0;
for (int i = 0; i < 2; i++) {
result += dp[n][i][0];
result += dp[n][i][1];
}
return result;
}
// Driver code
public static void main(String[] args) {
int N = 12;
System.out.println(findIntegers(N));
}
}
Python3
# code
# Python3 program to count number of
# binary strings without consecutive 1’s
# Function to find the number of integers
# less than or equal to N with no
# consecutive 1’s in binary representation
def findIntegers(num):
# Convert N to binary form
bin = ""
# Loop to convert N
# from Decimal to binary
while num > 0:
if num % 2 == 1:
bin += "1"
else:
bin += "0"
num //= 2
bin = bin[::-1]
n = len(bin)
# DP table to store the solutions
dp = [[[0 for i in range(2)] for j in range(2)] for k in range(n + 1)]
# Initializing the DP table
dp[0][0][0] = 1
# Loop through each digit
for i in range(1, n + 1):
for j in range(2):
for k in range(2):
limit = 1 if j else int(bin[i - 1])
for l in range(limit + 1):
if l == 1 and k == 1:
continue
dp[i][j | (l < limit)][l] += dp[i - 1][j][k]
# Calculating the result
result = 0
for i in range(2):
result += dp[n][i][0]
result += dp[n][i][1]
# return the final answer
return result
# Driver code
N = 12
print(findIntegers(N))
C#
using System;
class GFG {
// Function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
static int FindIntegers(int num)
{
// Convert N to binary form
string bin = "";
// Loop to convert N
// from Decimal to binary
while (num > 0) {
if (num % 2 == 1)
bin += "1";
else
bin += "0";
num /= 2;
}
char[] binArray = bin.ToCharArray();
Array.Reverse(binArray);
bin = new string(binArray);
int n = bin.Length;
// DP table to store the solutions
int[][][] dp = new int[n + 1][][];
for (int i = 0; i <= n; i++) {
dp[i] = new int[2][];
for (int j = 0; j < 2; j++) {
dp[i][j] = new int[2];
for (int k = 0; k < 2; k++) {
dp[i][j][k] = 0;
}
}
}
// Initializing the DP table
dp[0][0][0] = 1;
// Loop through each digit
for (int i = 1; i <= n; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
int limit
= (j == 1) ? 1 : (bin[i - 1] - '0');
for (int l = 0; l <= limit; l++) {
if (l == 1 && k == 1)
continue;
dp[i][j | ((l < limit) ? 1 : 0)][l]
+= dp[i - 1][j][k];
}
}
}
}
// Calculating the result
int result = 0;
for (int i = 0; i < 2; i++) {
result += dp[n][i][0];
result += dp[n][i][1];
}
return result;
}
// Driver code
public static void Main(string[] args)
{
int N = 12;
Console.WriteLine(FindIntegers(N));
}
}
JavaScript
// Javascript function to find the number of integers
// less than or equal to N with no
// consecutive 1’s in binary representation
function findIntegers(num) {
// Convert N to binary form
let bin = "";
// Loop to convert N
// from Decimal to binary
while (num > 0) {
if (num % 2)
bin += "1";
else
bin += "0";
num = Math.floor(num / 2);
}
bin = bin.split("").reverse().join("");
let n = bin.length;
// DP table to store the solutions
let dp = [];
for (let i = 0; i <= n; i++) {
dp[i] = [];
for (let j = 0; j < 2; j++) {
dp[i][j] = [];
for (let k = 0; k < 2; k++) {
dp[i][j][k] = 0;
}
}
}
// Initializing the DP table
dp[0][0][0] = 1;
// Loop through each digit
for (let i = 1; i <= n; i++) {
for (let j = 0; j < 2; j++) {
for (let k = 0; k < 2; k++) {
let limit = (j ? 1 : parseInt(bin[i - 1]));
for (let l = 0; l <= limit; l++) {
if (l == 1 && k == 1)
continue;
dp[i][j | (l < limit)][l] += dp[i - 1][j][k];
}
}
}
}
// Calculating the result
let result = 0;
for (let i = 0; i < 2; i++) {
result += dp[n][i][0];
result += dp[n][i][1];
}
// return the final answer
return result;
}
// Driver code
let N = 12;
console.log(findIntegers(N));
Time complexity: O(log N)
Auxiliary space: O(log N)
Explanation :
- The time complexity of the given code is O(log N), where N is the given input number. This is because the code loops through each digit of the binary representation of N, which has log N digits.
- The space complexity of the given code is O(log N), as well. This is because the code uses a DP table of size n+1 x 2 x 2, where n is the number of digits in the binary representation of N (i.e., log N). Since each element in the table is an integer, the total space used by the DP table is O(log N).
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Dijkstra's Algorithm to find Shortest Paths from a Source to all Given a weighted undirected graph represented as an edge list and a source vertex src, find the shortest path distances from the source vertex to all other vertices in the graph. The graph contains V vertices, numbered from 0 to V - 1.Note: The given graph does not contain any negative edge. Example
12 min read
Selection Sort Selection Sort is a comparison-based sorting algorithm. It sorts an array by repeatedly selecting the smallest (or largest) element from the unsorted portion and swapping it with the first unsorted element. This process continues until the entire array is sorted.First we find the smallest element an
8 min read