1. 问题:
给定N 个左括号[,M个右括号 ],其中M<=N,可以将其按任意顺序排列成长度为N+M的字符串,给定N,M的值,求所有合法的排列数目。
合法的排列方式是指:字符串中出现的每一个],必须有一个以出现的[与之匹配,例如,当N=3,M=1时 [[[ ]、[ ][[都是合法的排列,而:][[[不是合法的排列。
输入描述:
N M ,N属于[0,36),M属于[0,N] 例如:3 1
输出描述:
合法的排列数目,以十进制方式输出。例如: 3
示例1
输入 3 1
输出 3
注:(对应的三种排列为:[[[ ] 、[ ][[、[[ ][)
2. 问题分析:
本题可以使用动态规划进行解决。创建一个二维数组arrdp[M][N](注意:数组的索引从0开始),(N 为左括号[的数量,M为右括号 ]的数量),其中arrdp[i][j]的值是i+1个右括号和j+1个开括号所能组成的合法排列数目。
当有一个左括号,i+1个右括号时,arrdp[i][0]=1,当有一个右括号,j+1个左括号时,arrdp[0][j]=j+1。对只具有2个右括号的情况进行归纳总结,将结果填到下表中,进行归纳总结可得出公式:arrdp[i][j]=arrdp[i-1][j]+arrdp[i][j-1]。
3. java程序:
public class Demo4_1{
public static void main(String[] args){
// 动态规划
int N = 6;//左括号的数量
int M = 6; //右括号的数量
// 申请一个二维数组arrdp
//arrdp[i][j]表示i个右括号和j个左括号所能组成的合格数量
int [][] arrdp = new int[M][N];
// 当有1个右括号 N个左括号时arrdp对应的值
for(int i=0;i<N;i++){
arrdp[0][i] = i+1;
}
// 当有1个左括号 M个右括号时arrdp对应的值
for(int i=0;i<M;i++){
arrdp[i][0] = 1;
}
//arrdp[i][j]=arrdp[i-1][j]+arrdp[i][j-1]
for(int i=1;i<M;i++){
for(int j=1;j<N;j++){
arrdp[i][j] = arrdp[i-1][j]+arrdp[i][j-1];
}
}
System.out.println("合格的数量为:"+arrdp[M-1][N-1]);
}
}
4.运行结果: