给定一个整数 n 和一个位置数组 ‘position[]’ (1 <= length(position[]) <= 2n),找出长度为 2n 的合适括号表达式的方式数,使得给定的位置具有开括号。
注意: position[] 数组以(基于 1 的索引)[0, 1, 1, 0] 的形式给出。这里 1 表示应该放置开放括号的位置。在值为 0 的位置,可以放置左括号和右括号中的任何一个。
例子:
Input: n = 3, position[] = [0, 1, 0, 0, 0, 0]
Output: 3
The proper bracket sequences of length 6 and
opening bracket at position 2 are:
[ [ ] ] [ ]
[ [ [ ] ] ]
[ [ ] [ ] ]
Input: n = 2, position[] = [1, 0, 1, 0]
Output: 1
The only possibility is:
[ ] [ ]
这个问题的动态规划方法已经在这里讨论过。在这篇文章中,将讨论使用记忆方法的递归和递归。
算法——
- 将给定数组 adj 中所有带开括号的位置标记为 1。
- 运行一个递归循环,这样——
- 如果总括号数(从右括号减去左括号小于零),则返回 0。
- 如果索引达到n并且如果总括号=0,则获得解决方案并返回1,否则返回0。
- 如果索引预先分配了 1,则使用 index+1 递归返回函数并增加总括号。
- 否则通过在该索引处插入左括号并将总括号增加 1 + 在该索引处插入闭合括号并将总括号减少 1 并移动到下一个索引直到 n 来递归返回函数。
以下是上述算法的递归解决方案:
C++
// C++ implementation of above
// approach using Recursion
#include
using namespace std;
// Function to find Number of
// proper bracket expressions
int find(int index, int openbrk, int n, int adj[])
{
// If open-closed brackets < 0
if (openbrk < 0)
return 0;
// If index reaches the end of expression
if (index == n) {
// IF brackets are balanced
if (openbrk == 0)
return 1;
else
return 0;
}
// If the current index has assigned open bracket
if (adj[index] == 1) {
// Move forward increasing the
// length of open brackets
return find(index + 1, openbrk + 1, n, adj);
}
else {
// Move forward by inserting open as well
// as closed brackets on that index
return find(index + 1, openbrk + 1, n, adj)
+ find(index + 1, openbrk - 1, n, adj);
}
}
// Driver Code
int main()
{
int n = 2;
// Open brackets at position 1
int adj[4] = { 1, 0, 0, 0 };
// Calling the find function to calculate the answer
cout << find(0, 0, 2 * n, adj) << endl;
return 0;
}
Java
// Java implementation of above
// approach using Recursion
class Test {
// Function to find Number of
// proper bracket expressions
static int find(int index, int openbrk,
int n, int[] adj) {
// If open-closed brackets < 0
if (openbrk < 0) {
return 0;
}
// If index reaches the end of expression
if (index == n) {
// IF brackets are balanced
if (openbrk == 0) {
return 1;
} else {
return 0;
}
}
// If the current index has assigned open bracket
if (adj[index] == 1) {
// Move forward increasing the
// length of open brackets
return find(index + 1, openbrk + 1, n, adj);
} else {
// Move forward by inserting open as well
// as closed brackets on that index
return find(index + 1, openbrk + 1, n, adj)
+ find(index + 1, openbrk - 1, n, adj);
}
}
// Driver Code
public static void main(String[] args) {
int n = 2;
// Open brackets at position 1
int[] adj = {1, 0, 0, 0};
// Calling the find function to calculate the answer
System.out.print(find(0, 0, 2 * n, adj));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 implementation of above
# approach using memoizaion
N = 1000
# Function to find Number
# of proper bracket expressions
def find(index, openbrk, n, dp, adj):
# If open-closed brackets<0
if (openbrk < 0):
return 0
# If index reaches the end of expression
if (index == n):
# If brackets are balanced
if (openbrk == 0):
return 1
else:
return 0
# If already stored in dp
if (dp[index][openbrk] != -1):
return dp[index][openbrk]
# If the current index has assigned
# open bracket
if (adj[index] == 1):
# Move forward increasing the
# length of open brackets
dp[index][openbrk] = find(index + 1,
openbrk + 1, n, dp, adj)
else:
# Move forward by inserting open as
# well as closed brackets on that index
dp[index][openbrk] = (find(index + 1, openbrk + 1,
n, dp, adj) +
find(index + 1, openbrk - 1,
n, dp, adj))
# return the answer
return dp[index][openbrk]
# Driver Code
# DP array to precompute the answer
dp=[[-1 for i in range(N)]
for i in range(N)]
n = 2;
# Open brackets at position 1
adj = [ 1, 0, 0, 0 ]
# Calling the find function to
# calculate the answer
print(find(0, 0, 2 * n, dp, adj))
# This code is contributed by sahishelangia
C#
// C# implementation of above
// approach using Recursion
using System;
class GFG
{
// Function to find Number of
// proper bracket expressions
static int find(int index, int openbrk,
int n, int[] adj)
{
// If open-closed brackets < 0
if (openbrk < 0)
return 0;
// If index reaches the end of expression
if (index == n)
{
// IF brackets are balanced
if (openbrk == 0)
return 1;
else
return 0;
}
// If the current index has assigned open bracket
if (adj[index] == 1)
{
// Move forward increasing the
// length of open brackets
return find(index + 1, openbrk + 1, n, adj);
}
else
{
// Move forward by inserting open as well
// as closed brackets on that index
return find(index + 1, openbrk + 1, n, adj)
+ find(index + 1, openbrk - 1, n, adj);
}
}
// Driver Code
public static void Main()
{
int n = 2;
// Open brackets at position 1
int[] adj = { 1, 0, 0, 0 };
// Calling the find function to calculate the answer
Console.WriteLine(find(0, 0, 2 * n, adj));
}
}
// This code is contributed by Akanksha Rai
PHP
Javascript
C++
// C++ implementation of above
// approach using memoization
#include
using namespace std;
#define N 1000
// Function to find Number
// of proper bracket expressions
int find(int index, int openbrk, int n,
int dp[N][N], int adj[])
{
// If open-closed brackets<0
if (openbrk < 0)
return 0;
// If index reaches the end of expression
if (index == n) {
// If brackets are balanced
if (openbrk == 0)
return 1;
else
return 0;
}
// If already stored in dp
if (dp[index][openbrk] != -1)
return dp[index][openbrk];
// If the current index has assigned open bracket
if (adj[index] == 1) {
// Move forward increasing the
// length of open brackets
dp[index][openbrk] = find(index + 1,
openbrk + 1, n, dp, adj);
}
else {
// Move forward by inserting open as
// well as closed brackets on that index
dp[index][openbrk] = find(index + 1, openbrk + 1, n, dp, adj)
+ find(index + 1, openbrk - 1, n, dp, adj);
}
// return the answer
return dp[index][openbrk];
}
// Driver Code
int main()
{
// DP array to precompute the answer
int dp[N][N];
int n = 2;
memset(dp, -1, sizeof(dp));
// Open brackets at position 1
int adj[4] = { 1, 0, 0, 0 };
// Calling the find function to calculate the answer
cout << find(0, 0, 2 * n, dp, adj) << endl;
return 0;
}
Java
// Java implementation of above
// approach using memoization
public class GFG {
static final int N = 1000;
// Function to find Number
// of proper bracket expressions
static int find(int index, int openbrk, int n,
int dp[][], int adj[]) {
// If open-closed brackets<0
if (openbrk < 0) {
return 0;
}
// If index reaches the end of expression
if (index == n) {
// If brackets are balanced
if (openbrk == 0) {
return 1;
} else {
return 0;
}
}
// If already stored in dp
if (dp[index][openbrk] != -1) {
return dp[index][openbrk];
}
// If the current index has assigned open bracket
if (adj[index] == 1) {
// Move forward increasing the
// length of open brackets
dp[index][openbrk] = find(index + 1,
openbrk + 1, n, dp, adj);
} else {
// Move forward by inserting open as
// well as closed brackets on that index
dp[index][openbrk] = find(index + 1, openbrk + 1, n, dp, adj)
+ find(index + 1, openbrk - 1, n, dp, adj);
}
// return the answer
return dp[index][openbrk];
}
// Driver code
public static void main(String[] args) {
// DP array to precompute the answer
int dp[][] = new int[N][N];
int n = 2;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
dp[i][j] = -1;
}
}
// Open brackets at position 1
int adj[] = {1, 0, 0, 0};
// Calling the find function to calculate the answer
System.out.print(find(0, 0, 2 * n, dp, adj));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of above approach
# using memoization
N = 1000;
dp = [[-1 for x in range(N)]
for y in range(N)];
# Open brackets at position 1
adj = [ 1, 0, 0, 0 ];
# Function to find Number of proper
# bracket expressions
def find(index, openbrk, n):
# If open-closed brackets<0
if (openbrk < 0):
return 0;
# If index reaches the end of expression
if (index == n):
# If brackets are balanced
if (openbrk == 0):
return 1;
else:
return 0;
# If already stored in dp
if (dp[index][openbrk] != -1):
return dp[index][openbrk];
# If the current index has assigned
# open bracket
if (adj[index] == 1):
# Move forward increasing the
# length of open brackets
dp[index][openbrk] = find(index + 1,
openbrk + 1, n);
else:
# Move forward by inserting open as
# well as closed brackets on that index
dp[index][openbrk] = (find(index + 1, openbrk + 1, n) +
find(index + 1, openbrk - 1, n));
# return the answer
return dp[index][openbrk];
# Driver Code
# DP array to precompute the answer
n = 2;
# Calling the find function to
# calculate the answer
print(find(0, 0, 2 * n));
# This code is contributed by mits
C#
// C# implementation of above
// approach using memoization
using System;
class GFG
{
static readonly int N = 1000;
// Function to find Number
// of proper bracket expressions
static int find(int index, int openbrk, int n,
int [,]dp, int []adj)
{
// If open-closed brackets<0
if (openbrk < 0)
{
return 0;
}
// If index reaches the end of expression
if (index == n)
{
// If brackets are balanced
if (openbrk == 0)
{
return 1;
}
else
{
return 0;
}
}
// If already stored in dp
if (dp[index,openbrk] != -1)
{
return dp[index, openbrk];
}
// If the current index has assigned open bracket
if (adj[index] == 1)
{
// Move forward increasing the
// length of open brackets
dp[index, openbrk] = find(index + 1,
openbrk + 1, n, dp, adj);
}
else
{
// Move forward by inserting open as
// well as closed brackets on that index
dp[index, openbrk] = find(index + 1, openbrk + 1, n, dp, adj)
+ find(index + 1, openbrk - 1, n, dp, adj);
}
// return the answer
return dp[index,openbrk];
}
// Driver code
public static void Main()
{
// DP array to precompute the answer
int [,]dp = new int[N,N];
int n = 2;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
dp[i, j] = -1;
}
}
// Open brackets at position 1
int []adj = {1, 0, 0, 0};
// Calling the find function to calculate the answer
Console.WriteLine(find(0, 0, 2 * n, dp, adj));
}
}
// This code is contributed by PrinciRaj1992
PHP
Javascript
2
Memoized方法:时间上述算法的复杂度可以通过背诵进行优化。唯一要做的就是使用一个数组来存储之前迭代的结果,这样如果已经计算出值,就不需要多次递归调用同一个函数。
以下是所需的实现:
C++
// C++ implementation of above
// approach using memoization
#include
using namespace std;
#define N 1000
// Function to find Number
// of proper bracket expressions
int find(int index, int openbrk, int n,
int dp[N][N], int adj[])
{
// If open-closed brackets<0
if (openbrk < 0)
return 0;
// If index reaches the end of expression
if (index == n) {
// If brackets are balanced
if (openbrk == 0)
return 1;
else
return 0;
}
// If already stored in dp
if (dp[index][openbrk] != -1)
return dp[index][openbrk];
// If the current index has assigned open bracket
if (adj[index] == 1) {
// Move forward increasing the
// length of open brackets
dp[index][openbrk] = find(index + 1,
openbrk + 1, n, dp, adj);
}
else {
// Move forward by inserting open as
// well as closed brackets on that index
dp[index][openbrk] = find(index + 1, openbrk + 1, n, dp, adj)
+ find(index + 1, openbrk - 1, n, dp, adj);
}
// return the answer
return dp[index][openbrk];
}
// Driver Code
int main()
{
// DP array to precompute the answer
int dp[N][N];
int n = 2;
memset(dp, -1, sizeof(dp));
// Open brackets at position 1
int adj[4] = { 1, 0, 0, 0 };
// Calling the find function to calculate the answer
cout << find(0, 0, 2 * n, dp, adj) << endl;
return 0;
}
Java
// Java implementation of above
// approach using memoization
public class GFG {
static final int N = 1000;
// Function to find Number
// of proper bracket expressions
static int find(int index, int openbrk, int n,
int dp[][], int adj[]) {
// If open-closed brackets<0
if (openbrk < 0) {
return 0;
}
// If index reaches the end of expression
if (index == n) {
// If brackets are balanced
if (openbrk == 0) {
return 1;
} else {
return 0;
}
}
// If already stored in dp
if (dp[index][openbrk] != -1) {
return dp[index][openbrk];
}
// If the current index has assigned open bracket
if (adj[index] == 1) {
// Move forward increasing the
// length of open brackets
dp[index][openbrk] = find(index + 1,
openbrk + 1, n, dp, adj);
} else {
// Move forward by inserting open as
// well as closed brackets on that index
dp[index][openbrk] = find(index + 1, openbrk + 1, n, dp, adj)
+ find(index + 1, openbrk - 1, n, dp, adj);
}
// return the answer
return dp[index][openbrk];
}
// Driver code
public static void main(String[] args) {
// DP array to precompute the answer
int dp[][] = new int[N][N];
int n = 2;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
dp[i][j] = -1;
}
}
// Open brackets at position 1
int adj[] = {1, 0, 0, 0};
// Calling the find function to calculate the answer
System.out.print(find(0, 0, 2 * n, dp, adj));
}
}
// This code is contributed by 29AjayKumar
蟒蛇3
# Python3 implementation of above approach
# using memoization
N = 1000;
dp = [[-1 for x in range(N)]
for y in range(N)];
# Open brackets at position 1
adj = [ 1, 0, 0, 0 ];
# Function to find Number of proper
# bracket expressions
def find(index, openbrk, n):
# If open-closed brackets<0
if (openbrk < 0):
return 0;
# If index reaches the end of expression
if (index == n):
# If brackets are balanced
if (openbrk == 0):
return 1;
else:
return 0;
# If already stored in dp
if (dp[index][openbrk] != -1):
return dp[index][openbrk];
# If the current index has assigned
# open bracket
if (adj[index] == 1):
# Move forward increasing the
# length of open brackets
dp[index][openbrk] = find(index + 1,
openbrk + 1, n);
else:
# Move forward by inserting open as
# well as closed brackets on that index
dp[index][openbrk] = (find(index + 1, openbrk + 1, n) +
find(index + 1, openbrk - 1, n));
# return the answer
return dp[index][openbrk];
# Driver Code
# DP array to precompute the answer
n = 2;
# Calling the find function to
# calculate the answer
print(find(0, 0, 2 * n));
# This code is contributed by mits
C#
// C# implementation of above
// approach using memoization
using System;
class GFG
{
static readonly int N = 1000;
// Function to find Number
// of proper bracket expressions
static int find(int index, int openbrk, int n,
int [,]dp, int []adj)
{
// If open-closed brackets<0
if (openbrk < 0)
{
return 0;
}
// If index reaches the end of expression
if (index == n)
{
// If brackets are balanced
if (openbrk == 0)
{
return 1;
}
else
{
return 0;
}
}
// If already stored in dp
if (dp[index,openbrk] != -1)
{
return dp[index, openbrk];
}
// If the current index has assigned open bracket
if (adj[index] == 1)
{
// Move forward increasing the
// length of open brackets
dp[index, openbrk] = find(index + 1,
openbrk + 1, n, dp, adj);
}
else
{
// Move forward by inserting open as
// well as closed brackets on that index
dp[index, openbrk] = find(index + 1, openbrk + 1, n, dp, adj)
+ find(index + 1, openbrk - 1, n, dp, adj);
}
// return the answer
return dp[index,openbrk];
}
// Driver code
public static void Main()
{
// DP array to precompute the answer
int [,]dp = new int[N,N];
int n = 2;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
dp[i, j] = -1;
}
}
// Open brackets at position 1
int []adj = {1, 0, 0, 0};
// Calling the find function to calculate the answer
Console.WriteLine(find(0, 0, 2 * n, dp, adj));
}
}
// This code is contributed by PrinciRaj1992
PHP
Javascript
2
时间复杂度:O(N 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。