参考 generate-parentheses


版权声明:本文为博主原创文章,未经博主允许不得转载。
题目:http://oj.leetcode.com/problems/generate-parentheses/
描述:给定一个非负整数n,生成n对括号的所有合法排列。
解答:
该问题解的个数就是卡特兰数,但是现在不是求个数,而是要将所有合法的括号排列打印出来。
该问题和《编程之美》的买票找零问题一样,通过买票找零问题我们可以知道,针对一个长度为2n的合法排列,第1到2n个位置都满足如下规则:左括号的个数大于等于右括号的个数。所以,我们就可以按照这个规则去打印括号:假设在位置k我们还剩余left个左括号和right个右括号,如果left>0,则我们可以直接打印左括号,而不违背规则。能否打印右括号,我们还必须验证left和right的值是否满足规则,如果left>=right,则我们不能打印右括号,因为打印会违背合法排列的规则,否则可以打印右括号。如果left和right均为零,则说明我们已经完成一个合法排列,可以将其打印出来。通过深搜,我们可以很快地解决问题,针对n=2,问题的解空间如下:
按照这种思路,代码如下:
- void generate(int leftNum,int rightNum,string s,vector<string> &result)
- {
- if(leftNum==0&&rightNum==0)
- {
- result.push_back(s);
- }
- if(leftNum>0)
- {
- generate(leftNum-1,rightNum,s+'(',result);
- }
- if(rightNum>0&&leftNum<rightNum)
- {
- generate(leftNum,rightNum-1,s+')',result);
- }
- }
网上对该问题的解答非常多,无一例外都采用了递归,但是鲜见和上面思路如此清晰的算法。上述算法的思路是很多问题的通解,值得仔细研究。
作为一个例子,看一下数组的入栈出栈顺序问题:给定一个长度为n的不重复数组,求所有可能的入栈出栈顺序。该问题解的个数也是卡特兰数,根据上面的思路,我们也可以写出一个类似的代码:
- void inoutstack(int in,int out,deque<int> &q,stack<int> &s,deque<int> seq,vector<deque<int>> &result)
- {
- if(!in&&!out)
- {
- result.push_back(q);
- return;
- }
- if(in>0)
- {
- s.push(seq.front());
- seq.pop_front();
- inoutstack(in-1,out,q,s,seq,result);
- seq.push_front(s.top());
- s.pop();
- }
- if(out>0&&in<out)
- {
- q.push_back(s.top());
- s.pop();
- inoutstack(in,out-1,q,s,seq,result);
- s.push(q.back());
- q.pop_back();
- }
- }
上述代码由于采用了栈和队列模仿整个过程,所以显得略微复杂,但是代码的基本结构还是符合一个类似的基本规则:在某一个特定时刻,入栈的次数大于或者等于出栈的次数。在生成括号的问题中,我们利用一个string来保存结果,由于打印左括号时不影响打印右括号,所以无需复杂的状态恢复。在入栈出栈顺序问题中,由于两次递归调用共享同一个栈和队列,所以我们需要手动恢复其内容。在恢复时,队列会从头部删除和添加,所以我们采用了deque,它可以在头部添加和删除元素。queue只能在头部删除元素,所以没有采用。
参考 generate-parentheses的更多相关文章
- 72. Generate Parentheses && Valid Parentheses
Generate Parentheses Given a string containing just the characters '(', ')', '{', '}', '[' and ']', ...
- Generate Parentheses
Generate Parentheses Given n pairs of parentheses, write a function to generate all combinations of ...
- [LintCode] Generate Parentheses 生成括号
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- [CareerCup] 9.6 Generate Parentheses 生成括号
9.6 Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-p ...
- 【题解】【排列组合】【回溯】【Leetcode】Generate Parentheses
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- leetcode022. Generate Parentheses
leetcode 022. Generate Parentheses Concise recursive C++ solution class Solution { public: vector< ...
- [Leetcode][Python]22: Generate Parentheses
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 22: Generate Parentheseshttps://oj.leet ...
- N-Queens And N-Queens II [LeetCode] + Generate Parentheses[LeetCode] + 回溯法
回溯法 百度百科:回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步又一次选择,这样的走不通就退回再走的技术为回溯法 ...
- 22. Generate Parentheses(ML)
22. Generate Parentheses . Generate Parentheses Given n pairs of parentheses, write a function to ge ...
- leetcode-algorithms-22 Generate Parentheses
leetcode-algorithms-22 Generate Parentheses Given n pairs of parentheses, write a function to genera ...
随机推荐
- JavaScript 数组的常用操作
JavaScript splice 方法 splice 方法用于插入.删除或替换数组的元素.语法如下: array_object.splice(start, num, element1, elemen ...
- Java读写二进制文件示例
相对于文本文件,二进制文件读写快,定位快而准,下面是代码示例: import java.io.DataInput; import java.io.DataOutput; import java.io. ...
- springMVC 头像裁剪上传并等比压
第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,jquery.jcrop貌似并没有对 假设是ie下图片预览效果是滤镜做的 做出对应处理,也没有时间去改;仅仅好将就一下先把图片上传 ...
- 用Markdown写博客快速入门
Markdown,简单来说,就是一种可以方便转换为HTML的带标记符号纯文本. 它是对我等键盘党的福音:我不用再费劲挪动鼠标去按加粗.设置段落了,用键盘输入所有文本,一气呵成. 最重要的是,cnblo ...
- 《C++ Primer》 第四版 第7章 函数
<C++ Primer> 第四版 第7章 函数 思维导图笔记 超级具体.很具体,图片版,有利于复习查看 http://download.csdn.net/detail/onlyshi/94 ...
- win64 QT(VS2013) 配置 CGAL+libQGLViewer
网上讲的都不是太全 我来说说把~ 首先感谢这位大神: chenwk891:http://blog.csdn.net/chenwk891/article/details/42171495#reply 还 ...
- Java学习笔记1、常用dos命令
cd 改变当前目录 sys 制作DOS系统盘 copy 拷贝文件 del 删除文件 deltree 删除目录树 dir 列文件名 diskcopy 制磁盘 edit 文本编辑 format ...
- 关于org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor的队列
今天查看源码发现spring的线程池是支持队列的: 并且队列支持的上限相当大: 当线程池的达到最大线程时,默认会把任务放在队列(内存)中,所以我们可以放心用这个东西来写日志了
- 常见SQL Server导入导出数据的几个工具
摘自:http://www.cnblogs.com/chenxizhang/archive/2011/06/09/2076542.html 在我们的日常工作中,与数据库打交道的机会越来越多.这一篇文章 ...
- $("#SpecialAptitude").on("change",function(){CheckType($(this))})$("#SpecialAptitude").on("change",CheckType($(this)))
$("#SpecialAptitude").on("change",function(){CheckType($(this))})$("#Specia ...