Count even length binary sequences with same sum of first and second half bits
Last Updated :
12 Dec, 2022
Given a number n, find count of all binary sequences of length 2n such that sum of first n bits is same as sum of last n bits.
Examples:
Input: n = 1
Output: 2
There are 2 sequences of length 2*n, the
sequences are 00 and 11
Input: n = 2
Output: 6
There are 6 sequences of length 2*n, the
sequences are 0101, 0110, 1010, 1001, 0000
and 1111
The idea is to fix first and last bits and then recur for n-1, i.e., remaining 2(n-1) bits. There are following possibilities when we fix first and last bits.
1) First and last bits are same, remaining n-1 bits on both sides should also have the same sum.
2) First bit is 1 and last bit is 0, sum of remaining n-1 bits on left side should be 1 less than the sum n-1 bits on right side.
2) First bit is 0 and last bit is 1, sum of remaining n-1 bits on left side should be 1 more than the sum n-1 bits on right side.
Based on above facts, we get below recurrence formula.
diff is the expected difference between sum of first half digits and last half digits. Initially diff is 0.
// When first and last bits are same
// there are two cases, 00 and 11
count(n, diff) = 2*count(n-1, diff) +
// When first bit is 1 and last bit is 0
count(n-1, diff-1) +
// When first bit is 0 and last bit is 1
count(n-1, diff+1)
What should be base cases?
// When n == 1 (2 bit sequences)
1) If n == 1 and diff == 0, return 2
2) If n == 1 and |diff| == 1, return 1
// We can't cover difference of more than n with 2n bits
3) If |diff| > n, return 0
Below is the implementation based of above Naive Recursive Solution.
C++
#include<bits/stdc++.h>
using namespace std;
int countSeq( int n, int diff)
{
if ( abs (diff) > n)
return 0;
if (n == 1 && diff == 0)
return 2;
if (n == 1 && abs (diff) == 1)
return 1;
int res =
countSeq(n-1, diff+1) +
2*countSeq(n-1, diff) +
countSeq(n-1, diff-1);
return res;
}
int main()
{
int n = 2;
cout << "Count of sequences is "
<< countSeq(2, 0);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int countSeq( int n, int diff)
{
if (Math.abs(diff) > n)
return 0 ;
if (n == 1 && diff == 0 )
return 2 ;
if (n == 1 && Math.abs(diff) == 1 )
return 1 ;
int res =
countSeq(n- 1 , diff+ 1 ) +
2 *countSeq(n- 1 , diff) +
countSeq(n- 1 , diff- 1 );
return res;
}
public static void main(String[] args)
{
int n = 2 ;
System.out.println( "Count of sequences is "
+ countSeq( 2 , 0 ));
}
}
|
Python3
def countSeq(n, diff):
if ( abs (diff) > n):
return 0
if (n = = 1 and diff = = 0 ):
return 2
if (n = = 1 and abs (diff) = = 1 ):
return 1
res = (countSeq(n - 1 , diff + 1 ) +
2 * countSeq(n - 1 , diff) +
countSeq(n - 1 , diff - 1 ))
return res
n = 2 ;
print ( "Count of sequences is %d " %
(countSeq( 2 , 0 )))
|
C#
using System;
class GFG {
static int countSeq( int n, int diff)
{
if (Math.Abs(diff) > n)
return 0;
if (n == 1 && diff == 0)
return 2;
if (n == 1 && Math.Abs(diff) == 1)
return 1;
int res = countSeq(n-1, diff+1) +
2 * countSeq(n-1, diff) +
countSeq(n-1, diff-1);
return res;
}
public static void Main()
{
Console.Write( "Count of sequences is "
+ countSeq(2, 0));
}
}
|
PHP
<?php
function countSeq( $n , $diff )
{
if ( abs ( $diff ) > $n )
return 0;
if ( $n == 1 && $diff == 0)
return 2;
if ( $n == 1 && abs ( $diff ) == 1)
return 1;
$res =
countSeq( $n - 1, $diff + 1) +
2 * countSeq( $n - 1, $diff ) +
countSeq( $n - 1, $diff - 1);
return $res ;
}
$n = 2;
echo "Count of sequences is " ,
countSeq( $n , 0);
?>
|
Javascript
<script>
function countSeq(n,diff)
{
if (Math.abs(diff) > n)
return 0;
if (n == 1 && diff == 0)
return 2;
if (n == 1 && Math.abs(diff) == 1)
return 1;
let res =
countSeq(n-1, diff+1) +
2*countSeq(n-1, diff) +
countSeq(n-1, diff-1);
return res;
}
let n = 2;
document.write( "Count of sequences is "
+ countSeq(2, 0));
</script>
|
Output
Count of sequences is 6
The time complexity of above solution is exponential. If we draw the complete recursion tree, we can observer that many subproblems are solved again and again. For example, when we start from n = 4 and diff = 0, we can reach (3, 0) through multiple paths. Since same subproblems are called again, this problem has Overlapping subproblems property. So min square sum problem has both properties (see this and this) of a Dynamic Programming problem.
Below is a memoization based solution that uses a lookup table to compute the result.
C++
#include<bits/stdc++.h>
using namespace std;
#define MAX 1000
int lookup[MAX][MAX];
int countSeqUtil( int n, int dif)
{
if ( abs (dif) > n)
return 0;
if (n == 1 && dif == 0)
return 2;
if (n == 1 && abs (dif) == 1)
return 1;
if (lookup[n][n+dif] != -1)
return lookup[n][n+dif];
int res =
countSeqUtil(n-1, dif+1) +
2*countSeqUtil(n-1, dif) +
countSeqUtil(n-1, dif-1);
return lookup[n][n+dif] = res;
}
int countSeq( int n)
{
memset (lookup, -1, sizeof (lookup));
return countSeqUtil(n, 0);
}
int main()
{
int n = 2;
cout << "Count of sequences is "
<< countSeq(2);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int lookup[][] = new int [ 1000 ][ 1000 ];
static int countSeqUtil( int n, int dif)
{
if (Math.abs(dif) > n)
return 0 ;
if (n == 1 && dif == 0 )
return 2 ;
if (n == 1 && Math.abs(dif) == 1 )
return 1 ;
if (lookup[n][n+dif] != - 1 )
return lookup[n][n+dif];
int res =
countSeqUtil(n- 1 , dif+ 1 ) +
2 *countSeqUtil(n- 1 , dif) +
countSeqUtil(n- 1 , dif- 1 );
return lookup[n][n+dif] = res;
}
static int countSeq( int n)
{
for ( int k = 0 ; k < lookup.length; k++)
{
for ( int j = 0 ; j < lookup.length; j++)
{
lookup[k][j] = - 1 ;
}
}
return countSeqUtil(n, 0 );
}
public static void main(String[] args)
{
int n = 2 ;
System.out.println( "Count of sequences is "
+ countSeq( 2 ));
}
}
|
Python3
MAX = 1000
lookup = [[ 0 for i in range ( MAX )] for i in range ( MAX )]
def countSeqUtil(n,dif):
if abs (dif)>n:
return 0
if n = = 1 and dif = = 0 :
return 2
if n = = 1 and abs (dif) = = 1 :
return 1
if lookup[n][n + dif]! = - 1 :
return lookup[n][n + dif]
res = (countSeqUtil(n - 1 , dif + 1 ) +
2 * countSeqUtil(n - 1 , dif) +
countSeqUtil(n - 1 , dif - 1 ))
lookup[n][n + dif] = res
return res
def countSeq(n):
global lookup
lookup = [[ - 1 for i in range ( MAX )] for i in range ( MAX )]
res = countSeqUtil(n, 0 )
return res
if __name__ = = '__main__' :
n = 2
print ( 'Count of Sequences is ' ,countSeq(n))
|
C#
using System;
class GFG {
static int [,]lookup = new int [1000,1000];
static int countSeqUtil( int n, int dif)
{
if (Math.Abs(dif) > n)
return 0;
if (n == 1 && dif == 0)
return 2;
if (n == 1 && Math.Abs(dif) == 1)
return 1;
if (lookup[n,n+dif] != -1)
return lookup[n,n+dif];
int res =
countSeqUtil(n-1, dif+1) +
2*countSeqUtil(n-1, dif) +
countSeqUtil(n-1, dif-1);
return lookup[n,n+dif] = res;
}
static int countSeq( int n)
{
for ( int k = 0; k < lookup.GetLength(0); k++)
{
for ( int j = 0; j < lookup.GetLength(1); j++)
{
lookup[k,j] = -1;
}
}
return countSeqUtil(n, 0);
}
public static void Main()
{
int n = 2;
Console.WriteLine( "Count of sequences is "
+ countSeq(n));
}
}
|
PHP
<?php
$MAX = 1000;
$lookup = array_fill (0, $MAX ,
array_fill (0, $MAX , -1));
function countSeqUtil( $n , $dif )
{
global $lookup ;
if ( abs ( $dif ) > $n )
return 0;
if ( $n == 1 && $dif == 0)
return 2;
if ( $n == 1 && abs ( $dif ) == 1)
return 1;
if ( $lookup [ $n ][ $n + $dif ] != -1)
return $lookup [ $n ][ $n + $dif ];
$res =
countSeqUtil( $n - 1, $dif + 1) +
2 * countSeqUtil( $n - 1, $dif ) +
countSeqUtil( $n - 1, $dif - 1);
return $lookup [ $n ][ $n + $dif ] = $res ;
}
function countSeq( $n )
{
return countSeqUtil( $n , 0);
}
$n = 2;
echo "Count of sequences is " . countSeq( $n );
?>
|
Javascript
<script>
let lookup = new Array(1000);
for (let i = 0; i < 1000; i++)
{
lookup[i] = new Array(1000);
}
function countSeqUtil(n, dif)
{
if (Math.abs(dif) > n)
return 0;
if (n == 1 && dif == 0)
return 2;
if (n == 1 && Math.abs(dif) == 1)
return 1;
if (lookup[n][n + dif] != -1)
return lookup[n][n + dif];
let res =
countSeqUtil(n - 1, dif + 1) +
2*countSeqUtil(n - 1, dif) +
countSeqUtil(n - 1, dif - 1);
return lookup[n][n + dif] = res;
}
function countSeq(n)
{
for (let k = 0; k < lookup.length; k++)
{
for (let j = 0; j < lookup.length; j++)
{
lookup[k][j] = -1;
}
}
return countSeqUtil(n, 0);
}
let n = 2;
document.write( "Count of sequences is "
+ countSeq(2));
</script>
|
Output
Count of sequences is 6
Worst case time complexity of this solution is O(n2) as diff can be maximum n.
Below is O(n) solution for the same.
Number of n-bit strings with 0 ones = nC0
Number of n-bit strings with 1 ones = nC1
...
Number of n-bit strings with k ones = nCk
...
Number of n-bit strings with n ones = nCn
So, we can get required result using below
No. of 2*n bit strings such that first n bits have 0 ones &
last n bits have 0 ones = nC0 * nC0
No. of 2*n bit strings such that first n bits have 1 ones &
last n bits have 1 ones = nC1 * nC1
....
and so on.
Result = nC0*nC0 + nC1*nC1 + ... + nCn*nCn
= ?(nCk)2
0 <= k <= n
Below is the implementation based on above idea.
C++
#include<iostream>
using namespace std;
int countSeq( int n)
{
int nCr=1, res = 1;
for ( int r = 1; r<=n ; r++)
{
nCr = (nCr * (n+1-r))/r;
res += nCr*nCr;
}
return res;
}
int main()
{
int n = 2;
cout << "Count of sequences is "
<< countSeq(n);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int countSeq( int n)
{
int nCr = 1 , res = 1 ;
for ( int r = 1 ; r <= n; r++) {
nCr = (nCr * (n + 1 - r)) / r;
res += nCr * nCr;
}
return res;
}
public static void main(String args[])
{
int n = 2 ;
System.out.print( "Count of sequences is " );
System.out.println(countSeq(n));
}
}
|
Python
def countSeq(n):
nCr = 1
res = 1
for r in range ( 1 , n + 1 ):
nCr = (nCr * (n + 1 - r)) / r;
res + = nCr * nCr;
return res;
n = 2
print ( "Count of sequences is" ),
print ( int (countSeq(n)))
|
C#
using System;
class GFG {
static int countSeq( int n)
{
int nCr = 1, res = 1;
for ( int r = 1; r <= n ; r++)
{
nCr = (nCr * (n + 1 - r)) / r;
res += nCr * nCr;
}
return res;
}
public static void Main()
{
int n = 2;
Console.Write( "Count of sequences is " );
Console.Write(countSeq(n));
}
}
|
PHP
<?php
function countSeq( $n )
{
$nCr = 1;
$res = 1;
for ( $r = 1; $r <= $n ; $r ++)
{
$nCr = ( $nCr * ( $n + 1 - $r )) / $r ;
$res = $res + ( $nCr * $nCr );
}
return $res ;
}
$n = 2;
echo ( "Count of sequences is " );
echo countSeq( $n );
?>
|
Javascript
<script>
function countSeq(n)
{
let nCr = 1, res = 1;
for (let r = 1; r <= n ; r++)
{
nCr = (nCr * (n + 1 - r)) / r;
res += nCr * nCr;
}
return res;
}
let n = 2;
document.write( "Count of sequences is " );
document.write(countSeq(n));
</script>
|
Output
Count of sequences is 6
Thanks to d_geeks, Saurabh Jain and Mysterious Mind for suggesting above O(n) solution.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...