Balanced expressions such that given positions have opening brackets
Last Updated :
04 Dec, 2023
Given an integer n and an array of positions ‘position[]’ (1 <= position[i] <= 2n), find the number of ways of proper bracket expressions that can be formed of length 2n such that given positions have opening bracket.
Examples :
Input : n = 3, position[] = [2}
Output : 3
Explanation :
The proper bracket sequences of length 6 and
opening bracket at position 2 are:
[ [ ] ] [ ]
[ [ [ ] ] ]
[ [ ] [ ] ]
Input : n = 2, position[] = {1, 3}
Output : 1
Explanation: The only possibility is:
[ ] [ ]
Approach : This problem can be solved by Dynamic programming..
Let DPi, j be the number of valid ways of filling the first i positions such that there are j more brackets of type ‘[‘ than of type ‘]’. Valid ways would mean that it is the prefix of a matched bracket expression and that the locations at which enforced ‘[‘ brackets are enforced, have been satisfied. It is easy to see that DP2N, 0 is the final answer.
The base case of the DP is, DP0, 0=1. We need to fill the first position with a ‘[‘ bracket, and there is only way to do this.
If the position has a opening bracket sequence which can be marked by a hash array, then the recurrence occurs as :
if(j != 0) dpi, j = dpi-1, j-1
else dpi, j = 0;
If the position has no opening bracket sequence, then recurrence happens as :
if(j != 0) dpi, j = dpi - 1, j - 1 + dpi - 1, j + 1
else dpi, j = dpi - 1, j + 1
The answer will be DP2n, 0
Given below is the implementation of the above approach :
C++
#include <bits/stdc++.h>
using namespace std;
#define N 1000
long long arrangeBraces( int n, int pos[], int k)
{
bool h[N];
int dp[N][N];
memset (h, 0, sizeof h);
memset (dp, 0, sizeof dp);
for ( int i = 0; i < k; i++)
h[pos[i]] = 1;
dp[0][0] = 1;
for ( int i = 1; i <= 2 * n; i++) {
for ( int j = 0; j <= 2 * n; j++) {
if (h[i]) {
if (j != 0)
dp[i][j] = dp[i - 1][j - 1];
else
dp[i][j] = 0;
}
else {
if (j != 0)
dp[i][j] = dp[i - 1][j - 1] +
dp[i - 1][j + 1];
else
dp[i][j] = dp[i - 1][j + 1];
}
}
}
return dp[2 * n][0];
}
int main()
{
int n = 3;
int pos[] = { 2 };
int k = sizeof (pos)/ sizeof (pos[0]);
cout << arrangeBraces(n, pos, k);
return 0;
}
|
Java
public class GFG {
static final int N = 1000 ;
static long arrangeBraces( int n, int pos[], int k) {
boolean h[] = new boolean [N];
int dp[][] = new int [N][N];
for ( int i = 0 ; i < k; i++) {
h[pos[i]] = true ;
}
dp[ 0 ][ 0 ] = 1 ;
for ( int i = 1 ; i <= 2 * n; i++) {
for ( int j = 0 ; j <= 2 * n; j++) {
if (h[i]) {
if (j != 0 ) {
dp[i][j] = dp[i - 1 ][j - 1 ];
} else {
dp[i][j] = 0 ;
}
} else if (j != 0 ) {
dp[i][j] = dp[i - 1 ][j - 1 ]
+ dp[i - 1 ][j + 1 ];
} else {
dp[i][j] = dp[i - 1 ][j + 1 ];
}
}
}
return dp[ 2 * n][ 0 ];
}
public static void main(String[] args) {
int n = 3 ;
int pos[] = { 2 };
int k = pos.length;
System.out.print(arrangeBraces(n, pos, k));
}
}
|
Python3
N = 1000
def arrangeBraces(n, pos, k):
h = [ False for i in range (N)]
dp = [[ 0 for i in range (N)]
for i in range (N)]
for i in range (k):
h[pos[i]] = 1
dp[ 0 ][ 0 ] = 1
for i in range ( 1 , 2 * n + 1 ):
for j in range ( 2 * n + 1 ):
if (h[i]):
if (j ! = 0 ):
dp[i][j] = dp[i - 1 ][j - 1 ]
else :
dp[i][j] = 0
else :
if (j ! = 0 ):
dp[i][j] = (dp[i - 1 ][j - 1 ] +
dp[i - 1 ][j + 1 ])
else :
dp[i][j] = dp[i - 1 ][j + 1 ]
return dp[ 2 * n][ 0 ]
n = 3
pos = [ 2 ,];
k = len (pos)
print (arrangeBraces(n, pos, k))
|
C#
using System;
class GFG
{
static int N = 1000;
public static long arrangeBraces( int n, int [] pos, int k)
{
bool [] h = new bool [N];
int [,] dp = new int [N,N];
for ( int i = 0; i < N; i++)
h[i] = false ;
for ( int i = 0; i < N; i++)
for ( int j = 0; j < N; j++)
dp[i,j] = 0;
for ( int i = 0; i < k; i++)
h[pos[i]] = true ;
dp[0,0] = 1;
for ( int i = 1; i <= 2 * n; i++) {
for ( int j = 0; j <= 2 * n; j++) {
if (h[i]) {
if (j != 0)
dp[i,j] = dp[i - 1,j - 1];
else
dp[i,j] = 0;
}
else {
if (j != 0)
dp[i,j] = dp[i - 1,j - 1] +
dp[i - 1,j + 1];
else
dp[i,j] = dp[i - 1,j + 1];
}
}
}
return dp[2 * n,0];
}
static void Main()
{
int n = 3;
int [] pos = new int []{ 2 };
int k = pos.Length;
Console.Write(arrangeBraces(n, pos, k));
}
}
|
Javascript
<script>
let N = 1000;
function arrangeBraces(n, pos, k) {
let h = new Array(N);
h.fill( false );
let dp = new Array(N);
for (let i = 0; i < N; i++)
{
dp[i] = new Array(N);
for (let j = 0; j < N; j++)
{
dp[i][j] = 0;
}
}
for (let i = 0; i < k; i++) {
h[pos[i]] = true ;
}
dp[0][0] = 1;
for (let i = 1; i <= 2 * n; i++) {
for (let j = 0; j <= 2 * n; j++) {
if (h[i]) {
if (j != 0) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = 0;
}
} else if (j != 0) {
dp[i][j] = dp[i - 1][j - 1]
+ dp[i - 1][j + 1];
} else {
dp[i][j] = dp[i - 1][j + 1];
}
}
}
return dp[2 * n][0];
}
let n = 3;
let pos = [2];
let k = pos.length;
document.write(arrangeBraces(n, pos, k));
</script>
|
Time Complexity: O(n^2)
Auxiliary Space: O(n^2)
Efficient approach: Space optimization
In previous approach, the dp[i][j] is depend upon the current and previous row of 2D matrix. So to optimize space we use two vectors curr and dp that keep track of current and previous row of DP.
Implementation Steps:
- Initialize a vectors dp of size N+1 to keep track of only previous row of Dp matrix with 0.
- Now iterative over subproblems and get the current computation.
- While Initialize a vectors curr of size N+1 to keep track of only current row of Dp matrix with 0.
- Now compute the current value by the help of dp vector and store that value in curr.
- After every iteration store values of curr vector in dp vector for further iteration.
- At last return the answer stored in dp[0].
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
#define N 1000
long long arrangeBraces( int n, int pos[], int k)
{
bool h[N];
vector< int > dp(N + 1, 0);
memset (h, 0, sizeof h);
for ( int i = 0; i < k; i++)
h[pos[i]] = 1;
dp[0] = 1;
for ( int i = 1; i <= 2 * n; i++) {
vector< int > curr(N + 1, 0);
for ( int j = 0; j <= 2 * n; j++) {
if (h[i]) {
if (j != 0)
curr[j] = dp[j - 1];
else
curr[j] = 0;
}
else {
if (j != 0)
curr[j] = dp[j - 1] + dp[j + 1];
else
curr[j] = dp[j + 1];
}
}
dp = curr;
}
return dp[0];
}
int main()
{
int n = 3;
int pos[] = { 2 };
int k = sizeof (pos) / sizeof (pos[0]);
cout << arrangeBraces(n, pos, k);
return 0;
}
|
Java
import java.util.*;
public class Main {
static final int N = 1000 ;
static long arrangeBraces( int n, int pos[], int k)
{
boolean [] h = new boolean [N];
List<Integer> dp = new ArrayList<>(
Collections.nCopies(N + 1 , 0 ));
Arrays.fill(h, false );
for ( int i = 0 ; i < k; i++) {
h[pos[i]] = true ;
}
dp.set( 0 , 1 );
for ( int i = 1 ; i <= 2 * n; i++) {
List<Integer> curr = new ArrayList<>(
Collections.nCopies(N + 1 , 0 ));
for ( int j = 0 ; j <= 2 * n; j++) {
if (h[i]) {
if (j != 0 ) {
curr.set(j, dp.get(j - 1 ));
}
else {
curr.set(j, 0 );
}
}
else {
if (j != 0 ) {
curr.set(j, dp.get(j - 1 )
+ dp.get(j + 1 ));
}
else {
curr.set(j, dp.get(j + 1 ));
}
}
}
dp = curr;
}
return dp.get( 0 );
}
public static void main(String[] args)
{
int n = 3 ;
int pos[] = { 2 };
int k = pos.length;
System.out.println(arrangeBraces(n, pos, k));
}
}
|
Python3
def arrange_braces(n, pos):
h = [ False ] * 1001
dp = [ 0 ] * 1001
for i in range ( len (pos)):
h[pos[i]] = True
dp[ 0 ] = 1
for i in range ( 1 , 2 * n + 1 ):
curr = [ 0 ] * 1001
for j in range ( 2 * n + 1 ):
if h[i]:
if j ! = 0 :
curr[j] = dp[j - 1 ]
else :
curr[j] = 0
else :
if j ! = 0 :
curr[j] = dp[j - 1 ] + dp[j + 1 ]
else :
curr[j] = dp[j + 1 ]
dp = curr
return dp[ 0 ]
if __name__ = = "__main__" :
n = 3
pos = [ 2 ]
print (arrange_braces(n, pos))
|
C#
using System;
public class BracketArrangement
{
const int N = 1000;
static long ArrangeBraces( int n, int [] pos, int k)
{
bool [] h = new bool [N];
int [] dp = new int [N + 1];
Array.Fill(h, false );
for ( int i = 0; i < k; i++)
{
h[pos[i]] = true ;
}
dp[0] = 1;
for ( int i = 1; i <= 2 * n; i++)
{
int [] curr = new int [N + 1];
for ( int j = 0; j <= 2 * n; j++)
{
if (h[i])
{
if (j != 0)
curr[j] = dp[j - 1];
else
curr[j] = 0;
}
else
{
if (j != 0)
curr[j] = dp[j - 1] + dp[j + 1];
else
curr[j] = dp[j + 1];
}
}
dp = curr;
}
return dp[0];
}
static void Main()
{
int n = 3;
int [] pos = { 2 };
int k = pos.Length;
Console.WriteLine(ArrangeBraces(n, pos, k));
}
}
|
Javascript
function arrangeBraces(n, pos) {
let h = new Array(1001).fill( false );
let dp = new Array(1001).fill(0);
pos.forEach(p => {
h[p] = true ;
});
dp[0] = 1;
for (let i = 1; i <= 2 * n; i++) {
let curr = new Array(1001).fill(0);
for (let j = 0; j <= 2 * n; j++) {
if (h[i]) {
curr[j] = (j !== 0) ? dp[j - 1] : 0;
} else {
curr[j] = (j !== 0) ? dp[j - 1] + dp[j + 1] : dp[j + 1];
}
}
dp = curr;
}
return dp[0];
}
let n = 3;
let pos = [2];
console.log(arrangeBraces(n, pos));
|
Time complexity: O(N^2)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...