LeetCode c语言-Generate Parentheses和买票找零问题
来源:互联网 发布:软件采购进度报表 编辑:程序博客网 时间:2024/06/07 01:14
Title:
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:
[ "((()))", "(()())", "(())()", "()(())", "()()()"]
典型的递归+栈问题。一般碰到要输出很多种结果的问题,递归是第一考虑的思路。
对于这道题,符合要求的序列一定满足以下条件:
从左边开始数,右括号的个数一定不可能大于左括号,否则会出现))这种情况。
而且第一个一定是左括号。
代码如下:
solution:
/** * Return an array of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */void generate(char** result, int* Size, int l, int r, char* tmp, int index) { if(l==0 && r==0) { tmp[index]=0; result[*Size]=(char*)malloc(sizeof(char)*index); strcpy(result[*Size],tmp); (*Size)++; return; } if (l>0) { tmp[index]='('; generate(result, Size, l-1, r, tmp, index+1); } if(r>0 && l<r) { tmp[index]=')'; generate(result, Size, l, r-1, tmp, index+1); }}char** generateParenthesis(int n, int* returnSize) { char** result=(char**)malloc(sizeof(char)*1000000); char* tmp=(char*)malloc(sizeof(char)*(n*2+1)); int l=n,r=n; /* l和r分别表示左括号和右括号的剩余个数 */ *returnSize=0; generate(result,returnSize,l,r,tmp,0); return result; }
解析递归函数:
l和r表示剩余的左括号和右括号。
那么当l>0时,可以插入左括号,记住左括号是只要有就可以插入的。然后进行递归,记住l-1,表示减少一个。r不变。
if (l>0) { tmp[index]='('; generate(result, Size, l-1, r, tmp, index+1); }
if(r>0 && l<r) { tmp[index]=')'; generate(result, Size, l, r-1, tmp, index+1); }
当l==0 并且r==0,表明全部插入,这个时候说明这个序列是有效的,可以存起来并返回。
if(l==0 && r==0) { tmp[index]=0; result[*Size]=(char*)malloc(sizeof(char)*index); strcpy(result[*Size],tmp); (*Size)++; return; }
解析到这里,其实能够看出来,如果找到了左括号数量一定要大于右括号的隐含要求,再配合递归,其实非常简单。关键是能不能找到这个要求。
在《编程之美》一书中,也有类似的问题:买票找零
这道题其实和括号匹配问题是一样的,50元的相当于左括号,100元相当于右括号,一定要左括号大于右括号才能成立。
而且这种类型的题目牵扯到一个公式:Catalan number
比如对这道找零的题目进行数学分析:
分析1:队伍的序号标为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(2n)=f(0)*f(2n-2)+f(2)*f(2n-4)+······+f(2n-4)*f(2)+f(2n-2)*f(0)
并且令f(0)=1,再由组合数C(0,0)=0,可得
以上就是一种卡特兰数的通项公式。
Catalan 的应用场景:
1.出栈次序(买票问题)
对于一个无限大的栈,一共n个元素,请问有几种合法的入栈出栈形式?
分析:n个元素出栈入栈操作共有2n个,且任何前x个操作中入栈操作必须不少于出栈操作,直接用f(2n)计算即可。
2.括号化问题(矩阵连乘问题)
P = a1 * a2 * a3 * … * an,其中ai是矩阵。根据乘法结合律,不改变矩阵的相互顺序,只用括号表示成对的乘积,试问一共有几种括号化方案?
分析:n个矩阵相乘需要n-1对括号,且任何前x个元素中”(”的个数一定大于”)”的个数,所以应该为f(2(n-1))
3.街区对角问题
某个城市的某个居民,每天他须要走过2n个街区去上班(他在其住所以北n个街区和以东n个街区处工作)。如果他不跨越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路?
分析:其实也与括号问题相似,这个人一共要走2n步,其中向右与向上分别n步,那么,假设他第一步是向右的,那么之后的任何时刻,他向右的步数都不能少于想上的步数,即f(2n),当然,他也可以第一步时先向上,同样有f(2n)种走法,两者应该是以对角线对称的,所以答案为2*f(2n)。
- LeetCode c语言-Generate Parentheses和买票找零问题
- 买票找零问题
- 【C++】【LeetCode】22. Generate Parentheses
- 【Leetcode】:22. Generate Parentheses 问题 in Go语言
- LeetCode之Generate Parentheses(C++)
- 【LeetCode算法练习(C++)】Generate Parentheses
- Generate Parentheses [leetcode] 循环,DP和递归
- 买票找零
- 买票找零
- 买票找零
- 买票找零
- LeetCode: Generate Parentheses
- LeetCode: Generate Parentheses
- [Leetcode] Generate Parentheses
- leetcode 51: Generate Parentheses
- [LeetCode] Generate Parentheses
- Leetcode: Generate Parentheses
- LeetCode Generate Parentheses
- HashMap集合的使用
- @Resource
- sortedArrayUsingComparator
- RNN循环神经网络
- gcc 用法
- LeetCode c语言-Generate Parentheses和买票找零问题
- 【学习摘记】马士兵bbs初级版_课时14-15_login权限控制:session的典型用法
- Java实现——统计文件中字符串出现次数
- 通过http协议导出excel
- 2017中国容器技术使用情况有奖调查
- WebSocket 学习(五)--用socketIO实现聊天室
- TensorFlow
- DataBinding基本使用(4)
- 六个创建型模式1:简单工厂模式-Simple Factory Pattern【学习难度:★★☆☆☆,使用频率:★★★☆☆】