现在的位置: 首页 > 综合 > 正文

算法篇:神奇的卡塔兰数Catalan

2017年12月10日 ⁄ 综合 ⁄ 共 1828字 ⁄ 字号 评论关闭

这段时间复习数据结构,想起来这神奇的卡塔兰数
1.百科简介
卡塔兰数的来历:卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列。由以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名。
2.Catalan数的递推规律

由递推规律可知,前几项为:1,1,2,5,14,42,132,429,1430,4862,16796.。。
Catalan数的通项公式为:

3.Catalan数相关的问题解答

3.1.给定整数N,输出所有匹配的小括号序列。

例如:N=3

输出:

((()))
(()())
(())()
()(())
()()()

public static void brackets(int openStock, int closeStock, String s) {
        if (openStock == 0 && closeStock == 0) {//当开括号的数据和比括号的数目都为零时
            System.out.println(s);
        }
        //如果开括号数大于0,那么就添加一个开括号,开括号的数目-1,闭括号的数目+1
        if (openStock > 0) {
            brackets(openStock-1, closeStock+1, s + "(");
        }
        //如果闭括号的数目大于0,那么就添加一个闭括号,闭括号的数目-1
        if (closeStock > 0) {
            brackets(openStock, closeStock-1, s + ")");
        }
    }

调用:brackets(3,0,"");

2.所有可能的出栈序列

一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列。

例如:入栈序列为123,则出栈序列有:

321
231
213
132
123

package edu.njupt.zhb;
import java.util.Stack;
public class TestStackOut {
	private Stack<String> list = new Stack<String>();//待装入栈的序列,也用栈来实现
	private Stack<String> stack = new Stack<String>();//辅助栈
	private StringBuffer out = new StringBuffer();//输出串
	public  void popStackOrder(){//递归方法
		if(stack.empty() && list.empty()){//栈空,序列也空,则输出
			System.out.println(out);
			return;
		}
		if(!list.empty()){//将list栈中的元素转移到stack
			String str = list.pop();
			stack.push(str);
			popStackOrder();
			str = stack.pop();//复原
			list.push(str);//恢复栈
		}
		if(!stack.empty()){//
			String str = stack.pop();//出栈
			out.append(str);//记录出栈顺序
			popStackOrder();
			out.deleteCharAt(out.length()-1);//复原记录次序
			stack.push(str);//复原
		} 
	}
	public void test(){
		//注意,假设入栈序列是123,倒序装入list栈
		list.push("3");
		list.push("2");
		list.push("1");
		popStackOrder();
	}
	public static void main(String[] args) {
		new TestStackOut().test();
	}
}

类似的逻辑题还有:

电影院买票问题:

2n个人排队进电影院,票价是50美分。在这2n个人当中,其中n个人只有50美分,另外n个人有1美元(纸票子)。愚蠢的电影院开始卖票时1分钱也没有。问:有多少种排队方法使得每当一个拥有1美元买票时,电影院都有50美分找钱

注:1美元=100美分拥有1美元的人,拥有的是纸币,没法破成250美分

解答:很显然结果是卡塔兰数,这个和小括号问题很像。

更多Catalan数相关的问题可以参考:

[1]Catalan数解决的常见问题:http://blog.csdn.net/duanruibupt/article/details/6869431

[2]维基百科:http://zh.wikipedia.org/wiki/%E5%8D%A1%E5%A1%94%E5%85%B0%E6%95%B0

抱歉!评论已关闭.