分析:
关键:当前位置左括号不少于右括号
图是什么?
       节点:目前位置左括号和右括号数(x,y)(x>=y)
       边:从(x,y)到(x+1,y)和(x,y+1)
       x==y时,没有(x,y+1)这条边
解是什么?
        从(0,0)出发到(n,n)的全部路径
 
import java.util.ArrayList;
 
public class Solution {
    public void help(int n, int x, int y, String s, ArrayList<String> list)
    {
        // 终止条件
    if(y==n)
        {
            list.add(s);
        }
        if(x<n)
        {
            help(n,x+1,y,s+"(",list);
        }
        // 递归过程中 左括号x的个数必须大于等于右括号个数
        if(x>y)
        {
            help(n,x,y+1,s+")",list);
        }
    }
    
    public ArrayList<String> generateParenthesis(int n) {
    ArrayList<String> list = new ArrayList<String>();
        help(n,0,0,"",list);
        return list;
    }
}
 
===
2013-10-26 23:19 21255人阅读 评论(17) 收藏 举报
 分类:
leetcode(7) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

题目: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,问题的解空间如下:


按照这种思路,代码如下:

  1. void generate(int leftNum,int rightNum,string s,vector<string> &result)
  2. {
  3. if(leftNum==0&&rightNum==0)
  4. {
  5. result.push_back(s);
  6. }
  7. if(leftNum>0)
  8. {
  9. generate(leftNum-1,rightNum,s+'(',result);
  10. }
  11. if(rightNum>0&&leftNum<rightNum)
  12. {
  13. generate(leftNum,rightNum-1,s+')',result);
  14. }
  15. }

网上对该问题的解答非常多,无一例外都采用了递归,但是鲜见和上面思路如此清晰的算法。上述算法的思路是很多问题的通解,值得仔细研究。

作为一个例子,看一下数组的入栈出栈顺序问题:给定一个长度为n的不重复数组,求所有可能的入栈出栈顺序。该问题解的个数也是卡特兰数,根据上面的思路,我们也可以写出一个类似的代码:

  1. void inoutstack(int in,int out,deque<int> &q,stack<int> &s,deque<int> seq,vector<deque<int>> &result)
  2. {
  3. if(!in&&!out)
  4. {
  5. result.push_back(q);
  6. return;
  7. }
  8. if(in>0)
  9. {
  10. s.push(seq.front());
  11. seq.pop_front();
  12. inoutstack(in-1,out,q,s,seq,result);
  13. seq.push_front(s.top());
  14. s.pop();
  15. }
  16. if(out>0&&in<out)
  17. {
  18. q.push_back(s.top());
  19. s.pop();
  20. inoutstack(in,out-1,q,s,seq,result);
  21. s.push(q.back());
  22. q.pop_back();
  23. }
  24. }

上述代码由于采用了栈和队列模仿整个过程,所以显得略微复杂,但是代码的基本结构还是符合一个类似的基本规则:在某一个特定时刻,入栈的次数大于或者等于出栈的次数。在生成括号的问题中,我们利用一个string来保存结果,由于打印左括号时不影响打印右括号,所以无需复杂的状态恢复。在入栈出栈顺序问题中,由于两次递归调用共享同一个栈和队列,所以我们需要手动恢复其内容。在恢复时,队列会从头部删除和添加,所以我们采用了deque,它可以在头部添加和删除元素。queue只能在头部删除元素,所以没有采用。

 

参考 generate-parentheses的更多相关文章

  1. 72. Generate Parentheses && Valid Parentheses

    Generate Parentheses Given a string containing just the characters '(', ')', '{', '}', '[' and ']', ...

  2. Generate Parentheses

    Generate Parentheses Given n pairs of parentheses, write a function to generate all combinations of ...

  3. [LintCode] Generate Parentheses 生成括号

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  4. [CareerCup] 9.6 Generate Parentheses 生成括号

    9.6 Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-p ...

  5. 【题解】【排列组合】【回溯】【Leetcode】Generate Parentheses

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  6. leetcode022. Generate Parentheses

    leetcode 022. Generate Parentheses Concise recursive C++ solution class Solution { public: vector< ...

  7. [Leetcode][Python]22: Generate Parentheses

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 22: Generate Parentheseshttps://oj.leet ...

  8. N-Queens And N-Queens II [LeetCode] + Generate Parentheses[LeetCode] + 回溯法

    回溯法 百度百科:回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步又一次选择,这样的走不通就退回再走的技术为回溯法 ...

  9. 22. Generate Parentheses(ML)

    22. Generate Parentheses . Generate Parentheses Given n pairs of parentheses, write a function to ge ...

  10. leetcode-algorithms-22 Generate Parentheses

    leetcode-algorithms-22 Generate Parentheses Given n pairs of parentheses, write a function to genera ...

随机推荐

  1. [Android Pro] 注册 Google Play 开发者帐户

    官网地址: https://support.google.com/googleplay/android-developer/answer/6112435?hl=zh-Hans 博客地址: http:/ ...

  2. 使用JTextArea示例

    相对于JLabel显示提示文字,JTextArea有一个先天优势:文字可以拷贝出来.经过下面设置它也能在外观上和JLabel一致. 代码如下: JTextArea txtArea=new JTextA ...

  3. FastIV图像处理

    新建一图像处理算法群,主要讨论图像处理与计算机视觉中的快速算法及其工程实现. 群号码:322687422

  4. Java设计模式(十) 备忘录模式 状态模式

    (十九)备忘录模式 备忘录模式目的是保存一个对象的某个状态,在适当的时候恢复这个对象. class Memento{ private String value; public Memento(Stri ...

  5. 算法笔记_115:算法集训之代码填空题集二(Java)

     目录 1 连续数的公倍数 2 孪生素数 3 迷宫走法 4 拍7游戏 5 排列为平方数 6 平面点最小距离 7 扑克牌排列 8 三进制转十进制 9 识别复制串 10 蔬菜价格计算   1 连续数的公倍 ...

  6. 关于苹果开发证书失效的解决方式(2016年2月14日Failed to locate or generate matching signing assets)

    前言: 从2月14日開始,上传程序的同学可能会遇到提示上传失败的提示. 而且打开自己的钥匙串,发现所有的证书所有都显示此证书签发者无效. Failed to locate or generate ma ...

  7. Android so文件生成

    http://blog.csdn.net/laczff21/article/details/7542236 http://blog.csdn.net/yhm2046/article/details/8 ...

  8. C++ 代码风格准则:POD

    作者:一根筋的傻瓜链接:https://www.zhihu.com/question/36379130/answer/69853366来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  9. 安装Windows Service总是发生异常!

    打开VS2010 创建个windows服务应用程序!没有添加删除任何一行代码!然后按照下面的步骤 1. 将这个服务程序切换到设计视图2. 右击设计视图选择“添加安装程序”3. 切换到刚被添加的Proj ...

  10. android http post 请求与 json字符串

    一.目标 android客户端发送一个json格式的http的请求,期望得到服务端的一个json反馈. 1. 客户端发送的json格式为: {"data" : "valu ...