今天参加了阿里的线上笔试,其中有一道题,我只记得大体意思是这样的:
六组括号,可以嵌套,有多少种匹配方式?
其实这是一个很简单的卡塔兰数问题,对卡特兰数不了解的朋友可以到百度百科里了解一下,在此不再赘述,今天我来说说有万能解题法之称呼的解题法怎样解这个问题。
对于这个问题,我们可以看作是12个括号进栈问题,如果进栈的是“)”则弹出栈顶的“(”、“)”,每一次进栈要做以下检查:
1、如果是“(”则要求已经进栈的“(”数量要小于6,即 left<6;
2、如果是“)”则要求栈顶有”(“与之匹配,即 right<left;
剩下的问题就是将原问题分析为,12个括号依次进栈,这12个是”(“还是”)“的问题了,这就是一个标准的子集数问题,我们规定”(“为左子树,”)“为右子树
。下面是java实现代码。
package com.soft;
/**
* 张猛
* 2014年8月30日
*/
public class BracketsLineUp {
// 不变信息
static int n;
// 动态改变信息
static int left;// 记录“(”的数目
static int right;// 记录“)”的数目
static int count;// 记录解数目
/**
* @author zhangmeng
*TODO
*@param i 表示第i层,由第i个括号决定
*/
private static void trackback(int i) {
// 更新front
if (i < n) {
// 如果满足约束条件,搜索左子树
if (left < 6) {
// 搜索左子树
left++;
BracketsLineUp.trackback(i + 1);
//清理现场
left--;
}
// 如果 满足上界函数,搜索右子树
if (right < 6 && left >right) {
// 更新cx
right++;
trackback(i + 1);
//清理现场
right--;
}
}else{//处理第n层
count++;
return;
}
}
public static int LineUpCount() {
BracketsLineUp.n = 12;
BracketsLineUp.right = 0;
BracketsLineUp.left = 0;
BracketsLineUp.count = 0;
trackback(0);
return BracketsLineUp.count;
}
public static void main(String[] args) {
System.out.print(BracketsLineUp.LineUpCount());
}
}
运行结果:132