我们有:
n1
个{}
括号,
n2
个()
括号,
n3
个[]
括号,
我们可以拥有多少种不同的有效组合?
我的想法:我在java中编写了一个强力代码(下面有这个代码)并计算了所有可能的组合,我知道这是最糟糕的解决方案,
(该代码适用于我们可以使用不同类型括号的一般情况)
任何数学方法?
注1:有效组合通常定义,例如: {{()}}
:有效,{(}){}
:无效
注2:我们假设我们有2对{}
,1对()
和1对[]
,有效组合的数量将为168且数量为所有可能的(有效和无效)组合将是840
static void paranthesis_combination(char[] open , char[] close , int[] arr){
int l = 0;
for (int i = 0 ; i < arr.length ; i++)
l += arr[i];
l *= 2;
paranthesis_combination_sub(open , close , arr , new int[arr.length] , new int[arr.length], new StringBuilder(), l);
System.out.println(paran_count + " : " + valid_paran_count);
return;
}
static void paranthesis_combination_sub(char[] open , char[] close, int[] arr , int[] open_so_far , int[] close_so_far, StringBuilder strbld , int l){
if (strbld.length() == l && valid_paran(open , close , strbld)){
System.out.println(new String(strbld));
valid_paran_count++;
return;
}
for (int i = 0 ; i < open.length ; i++){
if (open_so_far[i] < arr[i]){
strbld.append(open[i]);
open_so_far[i]++;
paranthesis_combination_sub(open , close, arr , open_so_far , close_so_far, strbld , l);
open_so_far[i]--;
strbld.deleteCharAt(strbld.length() -1 );
}
}
for (int i = 0 ; i < open.length ; i++){
if (close_so_far[i] < open_so_far[i]){
strbld.append(close[i]);
close_so_far[i]++;
paranthesis_combination_sub(open , close, arr , open_so_far , close_so_far, strbld , l);
close_so_far[i]--;
strbld.deleteCharAt(strbld.length() -1 );
}
}
return;
}
答案 0 :(得分:4)
C
n
是第n个加泰罗尼亚数字C(2n,n)/(n+1)
,并提供仅使用{2n
的有效字符串数{1}}。因此,如果我们将所有()
和[]
更改为{}
,则会有()
C
方式。然后有n1+n2+n3
种方式将C(n1+n2+n3,n1)
n1
更改回()
,并{}
种方式将剩余的C(n2+n3,n3)
更改为()
}。把这些放在一起,有[]
种方法。
作为支票,当C(2n1+2n2+2n3,n1+n2+n3)C(n1+n2+n3,n1)C(n2+n3,n3)/(n1+n2+n3+1)
,n1=2
时,我们有n2=n3=1
。
答案 1 :(得分:0)
一般来说,无限。但是我假设你想找到有多少组合提供有限的字符串长度。为简单起见,我们假设限制是偶数。然后,让我们创建一个初始字符串:
(((...()...))),其长度等于限制。
然后,我们可以用[]或{}括号切换()对的任何实例。但是,如果我们改变一个左大括号,那么我们应该改变匹配的右大括号。所以,我们只能看开口支撑或成对。对于每个括号对,我们有4个选项:
保持不变
将其更改为[]
将其更改为{}
将其删除
因此,对于每个(l / 2)对象,我们选择四个标签中的一个,它给出: 4 ^(1/2)的可能性。
编辑:这假定只有“同心”括号字符串(彼此包含),正如您在编辑中所建议的那样。但直观地说,有效组合也是:()[] {} - 此解决方案不考虑这一点。