程式設計之美之買票找零
題目:假設有2N個人在排隊買票,其中有N個人手持50元的鈔票,另外有N個人手持100元的鈔票,假設開始售票時,售票處沒有零錢,問這2N個人有多少種排隊方式,不至使售票處出現找不開錢的局面?
分析:隊伍的序號標為0,1,...,2n-1,並把50元看作左括號,100元看作右括號,合法序列即括號能完成配對的序列。對於一個合法的序列,第0個一定是左括號,它必然與某個右括號配對,記其位置為k。那麼從1到k-1、k+1到2n-1也分別是兩個合法序列。那麼,k必然是奇數(1到k-1一共有偶數個),設k=2i+1。那麼剩餘括號的合法序列數為f(2i)*f(2n-2i-2)個。取i=0到n-1累加,並且令f(0)=1,則f(2n)
= ∑f(2i)*f(2n-2i-2),其中i = 0 ... n-1,最後的結果即為卡特蘭數。
我們們看leetcode上面有一個類似的問題,即
Generate Parentheses
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"
class Solution {
public:
void generateParenthesis(int left,int right,string parenthese,vector<string>& res)
{
if(left == 0 && right == 0)//得到一個結果
{
res.push_back(parenthese);
return;
}
if(left > 0)generateParenthesis(left - 1,right,parenthese + '(',res);
if(right > 0 && left < right)generateParenthesis(left,right-1,parenthese+')',res);
}
vector<string> generateParenthesis(int n)
{
vector<string> res;
if(n <= 0)return res;
generateParenthesis(n,n,"",res);
return res;
}
};
再看leetcode上的關於唯一二叉樹個數的問題,也是程式設計之美中買票找零的擴充套件問題:
Unique Binary Search Trees
Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
For example,
Given n = 3, there are a total of 5 unique BST's.
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
class Solution {
public:
int numTrees(int n) {
vector<int> num(n+1,0);
if(n <= 0)return 0;
num[0] = 1;
num[1] = 1;
int i,left,right;
for(i = 2; i <= n; ++i)//節點總數
{
for(left = 0; left < i; ++left)
{
right = i - left - 1;
num[i] += num[left] * num[right];//左子樹的個數 * 右子樹的個數
}
}
return num[n];
}
};
Unique Binary Search Trees II
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.
For example,
Given n = 3, your program should return all 5 unique BST's shown below.
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
confused what "{1,#,2,3}"
means? >
read more on how binary tree is serialized on OJ.
思路和上面的一樣,選取一個根節點,然後遞迴左右子樹,以該根節點為結果的數的個數是左右子樹的乘積,所以是一個二重迴圈
class Solution {
public:
vector<TreeNode *> generateTrees(int start,int end) {
vector<TreeNode*> res;
if(start > end)//空子樹
{
res.push_back(NULL);
return res;
}
int k;
for(k = start; k <= end; ++k)//根節點的位置
{
vector<TreeNode*> left = generateTrees(start,k-1);
vector<TreeNode*> right = generateTrees(k+1,end);
int i,j;
for(i = 0; i < left.size();++i)
{
for(j = 0; j < right.size();++j)
{
TreeNode* root = new TreeNode(k);//所有以該根節點為結果的樹
root -> left = left[i];
root -> right = right[j];
res.push_back(root);
}
}
}
return res;
}
vector<TreeNode *> generateTrees(int n) {
vector<TreeNode*> res;
res = generateTrees(1,n);
return res;
}
};
參考文獻:
http://blog.csdn.net/han_xiaoyang/article/details/11938973
從《程式設計之美》買票找零問題說起,娓娓道來卡特蘭數——兼爬坑指南
相關文章
- 程式設計之美複習筆記程式設計筆記
- 程式設計之美之高效安排見面會程式設計
- 程式設計之美之最短摘要生成程式設計
- 程式設計之美leetcode之編輯距離程式設計LeetCode
- Go併發程式設計之美-CAS操作Go程式設計
- Go併發程式設計之美-互斥鎖Go程式設計
- 程式碼之美---遞迴之美遞迴
- 程式設計之美初賽第一場--焦距程式設計
- 程式設計之美初賽第一場--樹程式設計
- 演算法字串位包含程式設計之美演算法字串程式設計
- 不錯的程式設計題之小明買書程式設計
- [程式設計之美][2.2] 不要被階乘嚇倒程式設計
- 程式設計之美之電話號碼對應英語單詞程式設計
- 品味Spring Cache設計之美Spring
- 重新領略設計模式之美設計模式
- 程式碼之美_感悟
- 《程式碼之美》 ——序
- 享受程式碼之美
- Java併發程式設計之美-千無萬喚使出來Java程式設計
- 微軟2程式設計之美2015資格賽微軟程式設計
- 《程式設計之美》舞動’08年IT圖書銷售奇蹟程式設計
- 同時找到最大值和最小值——程式設計之美程式設計
- [程式設計之美][3.10] 分層遍歷二叉樹程式設計二叉樹
- 程式設計之美:螞蟻爬杆問題的擴充套件程式設計套件
- 2013程式設計之美全國挑戰賽資格賽之傳話遊戲薦程式設計遊戲
- 《程式碼之美》的故事
- 細細品讀Retrofit的設計之美一
- 品味布隆過濾器的設計之美過濾器
- 細細品讀Retrofit的設計之美二
- 美圖秀秀-美化圖片之【特效】介面設計特效
- 簡約之美:如何實現簡約設計
- 求二進位制數中1的個數(程式設計之美)程式設計
- Linux 程式設計之Shell程式設計(轉)Linux程式設計
- 動態規劃系列之九找零錢動態規劃
- 程式之美 存乎於心
- 極簡網頁設計技巧,打造簡約之美網頁
- 演算法程式設計之美連續數之和等於某個數演算法程式設計
- 程式設計之美資格賽 大神與三位小夥伴(推公式)程式設計公式