Count of strings that can be formed using a, b and c under given constraints
Last Updated :
14 Dec, 2022
Given a length n, count the number of strings of length n that can be made using ‘a’, ‘b’ and ‘c’ with at most one ‘b’ and two ‘c’s allowed.
Examples :
Input : n = 3
Output : 19
Below strings follow given constraints:
aaa aab aac aba abc aca acb acc baa
bac bca bcc caa cab cac cba cbc cca ccb
Input : n = 4
Output : 39
Asked in Google Interview
A simple solution is to recursively count all possible combinations of strings that can be made up to latter ‘a’, ‘b’, and ‘c’.
Below is the implementation of the above idea
C++
#include<bits/stdc++.h>
using namespace std;
int countStr( int n, int bCount, int cCount)
{
if (bCount < 0 || cCount < 0) return 0;
if (n == 0) return 1;
if (bCount == 0 && cCount == 0) return 1;
int res = countStr(n-1, bCount, cCount);
res += countStr(n-1, bCount-1, cCount);
res += countStr(n-1, bCount, cCount-1);
return res;
}
int main()
{
int n = 3;
cout << countStr(n, 1, 2);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int countStr( int n,
int bCount,
int cCount)
{
if (bCount < 0 || cCount < 0 ) return 0 ;
if (n == 0 ) return 1 ;
if (bCount == 0 && cCount == 0 ) return 1 ;
int res = countStr(n - 1 , bCount, cCount);
res += countStr(n - 1 , bCount - 1 , cCount);
res += countStr(n - 1 , bCount, cCount - 1 );
return res;
}
public static void main (String[] args)
{
int n = 3 ;
System.out.println(countStr(n, 1 , 2 ));
}
}
|
Python 3
def countStr(n, bCount, cCount):
if (bCount < 0 or cCount < 0 ):
return 0
if (n = = 0 ) :
return 1
if (bCount = = 0 and cCount = = 0 ):
return 1
res = countStr(n - 1 , bCount, cCount)
res + = countStr(n - 1 , bCount - 1 , cCount)
res + = countStr(n - 1 , bCount, cCount - 1 )
return res
if __name__ = = "__main__" :
n = 3
print (countStr(n, 1 , 2 ))
|
C#
using System;
class GFG
{
static int countStr( int n,
int bCount,
int cCount)
{
if (bCount < 0 || cCount < 0)
return 0;
if (n == 0) return 1;
if (bCount == 0 && cCount == 0)
return 1;
int res = countStr(n - 1,
bCount, cCount);
res += countStr(n - 1,
bCount - 1, cCount);
res += countStr(n - 1,
bCount, cCount - 1);
return res;
}
static public void Main ()
{
int n = 3;
Console.WriteLine(countStr(n, 1, 2));
}
}
|
PHP
<?php
function countStr( $n , $bCount ,
$cCount )
{
if ( $bCount < 0 ||
$cCount < 0)
return 0;
if ( $n == 0)
return 1;
if ( $bCount == 0 &&
$cCount == 0)
return 1;
$res = countStr( $n - 1,
$bCount ,
$cCount );
$res += countStr( $n - 1,
$bCount - 1,
$cCount );
$res += countStr( $n - 1,
$bCount ,
$cCount - 1);
return $res ;
}
$n = 3;
echo countStr( $n , 1, 2);
?>
|
Javascript
<script>
function countStr(n, bCount, cCount)
{
if (bCount < 0 || cCount < 0) return 0;
if (n == 0) return 1;
if (bCount == 0 && cCount == 0) return 1;
let res = countStr(n - 1, bCount, cCount);
res += countStr(n - 1, bCount - 1, cCount);
res += countStr(n - 1, bCount, cCount - 1);
return res;
}
let n = 3;
document.write(countStr(n, 1, 2));
</script>
|
Time Complexity: O(3^N).
Auxiliary Space: O(1).
Efficient Solution:
If we drown a recursion tree of the above code, we can notice that the same values appear multiple times. So we store results that are used later if repeated.
C++
#include<bits/stdc++.h>
using namespace std;
int countStrUtil( int dp[][2][3], int n, int bCount=1,
int cCount=2)
{
if (bCount < 0 || cCount < 0) return 0;
if (n == 0) return 1;
if (bCount == 0 && cCount == 0) return 1;
if (dp[n][bCount][cCount] != -1)
return dp[n][bCount][cCount];
int res = countStrUtil(dp, n-1, bCount, cCount);
res += countStrUtil(dp, n-1, bCount-1, cCount);
res += countStrUtil(dp, n-1, bCount, cCount-1);
return (dp[n][bCount][cCount] = res);
}
int countStr( int n)
{
int dp[n+1][2][3];
memset (dp, -1, sizeof (dp));
return countStrUtil(dp, n);
}
int main()
{
int n = 3;
cout << countStr(n);
return 0;
}
|
Java
class GFG
{
static int countStrUtil( int [][][] dp, int n,
int bCount, int cCount)
{
if (bCount < 0 || cCount < 0 )
{
return 0 ;
}
if (n == 0 )
{
return 1 ;
}
if (bCount == 0 && cCount == 0 )
{
return 1 ;
}
if (dp[n][bCount][cCount] != - 1 )
{
return dp[n][bCount][cCount];
}
int res = countStrUtil(dp, n - 1 , bCount, cCount);
res += countStrUtil(dp, n - 1 , bCount - 1 , cCount);
res += countStrUtil(dp, n - 1 , bCount, cCount - 1 );
return (dp[n][bCount][cCount] = res);
}
static int countStr( int n, int bCount, int cCount)
{
int [][][] dp = new int [n + 1 ][ 2 ][ 3 ];
for ( int i = 0 ; i < n + 1 ; i++)
{
for ( int j = 0 ; j < 2 ; j++)
{
for ( int k = 0 ; k < 3 ; k++)
{
dp[i][j][k] = - 1 ;
}
}
}
return countStrUtil(dp, n,bCount,cCount);
}
public static void main(String[] args)
{
int n = 3 ;
int bCount = 1 , cCount = 2 ;
System.out.println(countStr(n,bCount,cCount));
}
}
|
Python3
def countStrUtil(dp, n, bCount = 1 ,cCount = 2 ):
if (bCount < 0 or cCount < 0 ):
return 0
if (n = = 0 ):
return 1
if (bCount = = 0 and cCount = = 0 ):
return 1
if (dp[n][bCount][cCount] ! = - 1 ):
return dp[n][bCount][cCount]
res = countStrUtil(dp, n - 1 , bCount, cCount)
res + = countStrUtil(dp, n - 1 , bCount - 1 , cCount)
res + = countStrUtil(dp, n - 1 , bCount, cCount - 1 )
dp[n][bCount][cCount] = res
return dp[n][bCount][cCount]
def countStr(n):
dp = [ [ [ - 1 for x in range ( 2 + 1 )] for y in range ( 1 + 1 )] for z in range (n + 1 )]
return countStrUtil(dp, n)
if __name__ = = "__main__" :
n = 3
print (countStr(n))
|
C#
using System;
class GFG
{
static int countStrUtil( int [,,] dp, int n,
int bCount=1, int cCount=2)
{
if (bCount < 0 || cCount < 0)
return 0;
if (n == 0)
return 1;
if (bCount == 0 && cCount == 0)
return 1;
if (dp[n,bCount,cCount] != -1)
return dp[n,bCount,cCount];
int res = countStrUtil(dp, n - 1, bCount, cCount);
res += countStrUtil(dp, n - 1, bCount - 1, cCount);
res += countStrUtil(dp, n - 1, bCount, cCount - 1);
return (dp[n, bCount, cCount] = res);
}
static int countStr( int n)
{
int [,,] dp = new int [n + 1, 2, 3];
for ( int i = 0; i < n + 1; i++)
for ( int j = 0; j < 2; j++)
for ( int k = 0; k < 3; k++)
dp[i, j, k] = -1;
return countStrUtil(dp, n);
}
static void Main()
{
int n = 3;
Console.Write(countStr(n));
}
}
|
Javascript
<script>
function countStrUtil(dp , n, bCount , cCount)
{
if (bCount < 0 || cCount < 0)
{
return 0;
}
if (n == 0)
{
return 1;
}
if (bCount == 0 && cCount == 0)
{
return 1;
}
if (dp[n][bCount][cCount] != -1)
{
return dp[n][bCount][cCount];
}
var res = countStrUtil(dp, n - 1, bCount, cCount);
res += countStrUtil(dp, n - 1, bCount - 1, cCount);
res += countStrUtil(dp, n - 1, bCount, cCount - 1);
return (dp[n][bCount][cCount] = res);
}
function countStr(n , bCount , cCount)
{
dp = Array(n+1).fill(0).map
(x => Array(2).fill(0).map
(x => Array(3).fill(0)));
for (i = 0; i < n + 1; i++)
{
for (j = 0; j < 2; j++)
{
for (k = 0; k < 3; k++)
{
dp[i][j][k] = -1;
}
}
}
return countStrUtil(dp, n,bCount,cCount);
}
var n = 3;
var bCount = 1, cCount = 2;
document.write(countStr(n,bCount,cCount));
</script>
|
Time Complexity : O(n)
Auxiliary Space : O(n)
Thanks to Mr. Lazy for suggesting above solutions.
A solution that works in O(1) time :
We can apply the concepts of combinatorics to solve this problem in constant time. we may recall the formula that the number of ways we can arrange a total of n objects, out of which p number of objects are of one type, q objects are of another type, and r objects are of the third type is n!/(p!q!r!)
Let us proceed towards the solution step by step.
How many strings we can form with no ‘b’ and ‘c’? The answer is 1 because we can arrange a string consisting of only ‘a’ in one way only and the string would be aaaa….(n times).
How many strings we can form with one ‘b’? The answer is n because we can arrange a string consisting (n-1) ‘a’s and 1 ‘b’ is n!/(n-1)! = n . The same goes for ‘c’ .
How many strings we can form with 2 places, filled up by ‘b’ and/or ‘c’ ? Answer is n*(n-1) + n*(n-1)/2 . Because that 2 places can be either 1 ‘b’ and 1 ‘c’ or 2 ‘c’ according to our given constraints. For the first case, total number of arrangements is n!/(n-2)! = n*(n-1) and for second case that is n!/(2!(n-2)!) = n*(n-1)/2 .
Finally, how many strings we can form with 3 places, filled up by ‘b’ and/or ‘c’ ? Answer is (n-2)*(n-1)*n/2 . Because those 3 places can only be consisting of 1 ‘b’ and 2’c’ according to our given constraints. So, total number of arrangements is n!/(2!(n-3)!) = (n-2)*(n-1)*n/2 .
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int countStr( int n){
int count = 0;
if (n>=1){
count += 1;
count += n;
count += n;
if (n>=2){
count += n*(n-1);
count += n*(n-1)/2;
if (n>=3){
count += (n-2)*(n-1)*n/2;
}
}
}
return count;
}
int main()
{
int n = 3;
cout << countStr(n);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int countStr( int n)
{
return 1 + (n * 2 ) +
(n * ((n * n) - 1 ) / 2 );
}
public static void main (String[] args)
{
int n = 3 ;
System.out.println( countStr(n));
}
}
|
Python 3
def countStr(n):
return ( 1 + (n * 2 ) +
(n * ((n * n) - 1 ) / / 2 ))
if __name__ = = "__main__" :
n = 3
print (countStr(n))
|
C#
using System;
class GFG
{
static int countStr( int n)
{
return 1 + (n * 2) +
(n * ((n * n) - 1) / 2);
}
static public void Main ()
{
int n = 3;
Console.WriteLine(countStr(n));
}
}
|
PHP
<?php
function countStr( $n )
{
return 1 + ( $n * 2) + ( $n *
(( $n * $n ) - 1) / 2);
}
$n = 3;
echo countStr( $n );
?>
|
Javascript
<script>
function countStr(n) {
return 1 + (n * 2) + (n * ((n * n) - 1) / 2);
}
var n = 3;
document.write(countStr(n));
</script>
|
Time Complexity : O(1)
Auxiliary Space : O(1)
Thanks to Niharika Sahai for providing above solution.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...