LeetCode(22)GenerateParentheses

题目如下:
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:

"((()))", "(()())", "(())()", "()(())", "()()()"

题目意思是说,给出所有的合法的括号形式。比如,手动地来写写。

n=1时,  "()"

n=2时,"()()", "(())"

n=3时,"((()))", "(()())", "(())()", "()(())", "()()()"

这个问题比较适合用递归来解决。经过一些探索,想到一个比较自然也比较好理解的办法。描述如下:

当n=1时,显然只能写出"()"

当n=2时,为什么写出了"()()", "(())",这和n=1时候的结果有什么关系呢?你可以看成有个基本元素element="()",它尝试把它本身放入上一次的结果中,也就是n=1的结果中。

当n=1时,  观察下面这个表达式

| ( | ) |

可以认为,对上面表达式中的三个竖线而言,每个竖线都是一个候选的插入位置。

如果把element="()" 插入竖线一,将构成()()

如果把element="()" 插入竖线二,将构成(())

如果把element="()" 插入竖线三,将构成()()

其中过滤掉重复,最后得到当n=2时,合法的括号形式为"()()", "(())"

把上面的思考写成code,如下

//
//  Solution.h
//  LeetCodeOJ_021_GeneratePairsOfParenthese
//
//  Created by feliciafay on 12/18/13.
//  Copyright (c) 2013 feliciafay. All rights reserved.
//

#ifndef LeetCodeOJ_021_GeneratePairsOfParenthese_Solution_h
#define LeetCodeOJ_021_GeneratePairsOfParenthese_Solution_h
#include <vector>
#include <iostream>
#include <set>
#include <string>
#include <cmath>
using namespace std;

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        if(n<1){
            vector<string> res_vec;
            return res_vec;
        }
        else if(n==1){
            vector<string> res_vec;
            res_vec.push_back("()");
            return res_vec;
        }else{
            vector<string> pre_vec=generateParenthesis(n-1);
            set<string> filter_set;
            vector<string> res_vec;
            for(int i=0;i<pre_vec.size();i++){
                string pre_str=pre_vec[i];
                int pre_str_len=(int)pre_str.length();
                for(int j=0;j<=pre_str_len;j++){
                    string now_str=pre_str.substr(0,j)+"()"+pre_str.substr(j,pre_str_len-j);
                    if(filter_set.find(now_str)==filter_set.end()){
                        filter_set.insert(now_str);
                        res_vec.push_back(now_str);
                    }
                }
                string now_str=pre_str+"()";
                if(filter_set.find(now_str)==filter_set.end()){
                    filter_set.insert(now_str);
                    res_vec.push_back(now_str);
                }
            }
            return res_vec;
        }
    }
};

#endif

小结

(1) 一开始思考进入误区,写了很久输出结果总是不全。后来换了角度看问题,终于正确了。

(2) 这个题目背后的奥秘是卡特兰数,这个目前还没有开始看,稍后更新。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值