JavaScript Program to Count Strings with Consecutive 1’s
Last Updated :
06 Nov, 2023
Given a number n, count the Optimized number of n-length strings with consecutive 1s in them.
Examples:
Input : n = 2
Output : 1
There are 4 strings of length 2, the
strings are 00, 01, 10 and 11. Only the
string 11 has consecutive 1's.
Input : n = 3
Output : 3
There are 8 strings of length 3, the
strings are 000, 001, 010, 011, 100,
101, 110 and 111. The strings with
consecutive 1's are 011, 110 and 111.
Input : n = 5
Output : 19
Naive Approach:
- We’ve created a variable called “ans,” which serves as a counter to keep track of how many strings contain two consecutive ones.
- Our approach involves generating all possible binary strings of a specified length using a recursive technique that involves picking and not picking of elements.
- Once we’ve generated these strings, we examine each one to determine if it contains two or more consecutive ones.
- If so, we increment the “ans” variable by 1 to keep count.
- In the end, we simply output the value stored in the “ans” variable, which represents the total number of strings with at least two consecutive ones.
Example: This example shows the use of the above-explained approach.
Javascript
function countBinaryStringsWithConsecutiveOnes(
n, currentIndex, currentString, answer) {
if (currentIndex == n) {
let count = 0;
let tempCount = 0;
for (let i = 0; i < n; i++) {
if (
currentString.charAt(i) == "1" ) {
tempCount++;
} else {
tempCount = 0;
}
count = Math.max(count, tempCount);
}
if (count >= 2) {
answer[0]++;
}
return ;
}
countBinaryStringsWithConsecutiveOnes(
n, currentIndex + 1, currentString + "0" , answer);
countBinaryStringsWithConsecutiveOnes(
n, currentIndex + 1, currentString + "1" , answer);
}
let answer = [0];
countBinaryStringsWithConsecutiveOnes(11, 0, "" , answer);
console.log(answer[0]);
|
Time Complexity: O((2^n) * n), “2^n” for generating all strings, and “n” for traversing each string to count the maximum number of consecutive ones.
Auxiliary Space: O(n),Recursion Stack Space.
Optimized Approach:
To address the reverse problem of counting strings that don’t contain consecutive 1’s, we can utilize a Dynamic Programming solution, as explained in a separate solution (see here). We can leverage that solution to find the count we need by following these steps:
- Calculate the number of binary strings without consecutive 1’s using the method outlined in the mentioned solution. Let’s denote this count as “c.”
- The total count of all possible binary strings of length “n” is 2^n.
- To find the total count of binary strings with consecutive 1’s, subtract “c” from 2^n.
Example: This example shows the use of the above-explained approach.
Javascript
function countBinaryStringsWithoutConsecutiveOnes(n) {
let endingWithZero = [];
let endingWithOne = [];
endingWithZero[0] =
endingWithOne[0] = 1;
for (let i = 1; i < n; i++) {
endingWithZero[i] =
endingWithZero[i - 1] +
endingWithOne[i - 1];
endingWithOne[i] =
endingWithZero[i - 1];
}
return (
(1 << n) - endingWithZero[n - 1] - endingWithOne[n - 1]
);
}
console.log(
countBinaryStringsWithoutConsecutiveOnes(11)
);
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Optimization:
The time complexity of the previous solution is O(n). We can enhance the efficiency of the solution to operate in O(Logn) time. When we closely examine the pattern of counting strings without consecutive 1’s, we can discern that the count is, in fact, the (n+2)th Fibonacci number for n >= 1. The Fibonacci Numbers sequence is as follows: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 141, and so on.
n = 1, count = 0 = 21 - fib(3)
n = 2, count = 1 = 22 - fib(4)
n = 3, count = 3 = 23 - fib(5)
n = 4, count = 8 = 24 - fib(6)
n = 5, count = 19 = 25 - fib(7)
................
This optimization allows us to calculate the count much more efficiently using the Fibonacci sequence.
Example: This example shows the use of the above-explained approach.
Javascript
function fib(n) {
let F = [
[1, 1],
[1, 0],
];
if (n === 0) {
return 0;
}
power(F, n - 1);
return F[0][0];
}
function multiply(F, M) {
let x = F[0][0] * M[0][0] +
F[0][1] * M[1][0];
let y = F[0][0] * M[0][1] +
F[0][1] * M[1][1];
let z = F[1][0] * M[0][0] +
F[1][1] * M[1][0];
let w = F[1][0] * M[0][1] +
F[1][1] * M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
function power(F, n) {
if (n <= 1) {
return ;
}
let M = [
[1, 1],
[1, 0],
];
power(F, Math.floor(n / 2));
multiply(F, F);
if (n % 2 !== 0) {
multiply(F, M);
}
}
let n = 11;
console.log(Math.pow(2, n) - fib(n + 2));
|
Time Complexity: O(logN)
Share your thoughts in the comments
Please Login to comment...