【LeetCode】22. Generate Parentheses

我的解法(元素顺序和答案不对)

思路:

  • 简单测试了一下之后,发现我只需要构造该vector<string>中元素即可。不需要我输出“[]”和“”。
  • n=1时,item应该是“()”;
  • n=2时,item有2个:“(())”和“()()”;
  • n=3时,item有5个:"((()))"、"(()())"、"(())()"、"()(())"、"()()()"
  • 我找到的规律是:(1)先给上一个结果中的每个元素加外括号"()" (2)给上一个结果的最后一个加一个小括号"()" (3)分别除最后一个元素外的其他元素,右侧和左侧分别加括号"()"、"()"

代码:

class Solution {
public:
    vector<string> generateParenthesis(int n) 
    {
         vector<string> ans;        
         if(n==1)
         {    
             string item="()";
             ans.push_back(item);                
         }
         else
         {
             vector<string> last=generateParenthesis(n-1);//取得上次结果的所有元素 
             string item;             
             for(int j=0;j<last.size();j++)
             {
                item="("+last[j]+")";//给每一个元素的外面加一个括号
                ans.push_back(item);                                             
             } 
             for(int j=0;j<last.size()-1;j++)
             {                
                item=last[j]+"()"; //除了最后一个之外,在右边加括号     
                ans.push_back(item);                                                             
             } 
             for(int j=0;j<last.size()-1;j++)
             {   
                item="()"+last[j];  //除了最后一个之外,在左边加括号  
                ans.push_back(item);                                               
             } 
             item=last[last.size()-1]+"()";//最后一个在右边加括号
             ans.push_back(item);
         }
        return ans;
    }
};

评论:明明题目中说,得到所有结果即可呀!为什么还要对顺序作要求呢?看来是有固定解法。

 

正确解法:

看了solution,也看了几个博主的答案后,终于理解了这种思路。

思路:

  • 溯源算法:可以理解为是一种试探性的全局搜索。穷举出每一种可能性,把所有成功的解都返回解空间的一种算法。

     (对于这种列出所有结果的题首先还是考虑用递归Recursion来解。)

  • 递归:在理解递归的时候不要进入函数的内部做嵌套,而应该把他理解成一个黑盒子。彻底把函数抽象出来,只考虑函数的输入输出,实现效果。
  • 递归过程
  • 回归条件:逐步生成左右括号,当数量都达到最大值n时,那么把解返回解空间。

    选择条件1:如果左括号还不够,那么就递归。

    递归关系: 如果左括号还不够,那么就用掉一个左括号(字符串+“(”,函数中left-1)

    选择条件2:如果右括号小于左括号数量,那么就递归。(如果在某次递归时,字符串中右括号的个数大于左括号的个数,即会出现')('这样的非法串,所以这种情况不处理。)

    递归关系: 用掉一个右括号。

  • 递归是怎么回退的?dfs。深度优先搜索。如下图所示(源自讨论区):n=2时的所有情况。只有满足leftNum<=2,和rightNum<=leftNum的才可以。

代码:

class Solution {
public:
    void generate(vector<string>&ans,string curStr,int leftNum,int rightNum,int max){
        if(leftNum==max&&rightNum==max){
            ans.push_back(curStr);   
            return;
        }       
        if(leftNum<max) {
            generate(ans,curStr+"(",leftNum+1,rightNum,max);
        }
        if(rightNum<leftNum){            
            generate(ans,curStr+")",leftNum,rightNum+1,max);
        }     
    }
    vector<string> generateParenthesis(int n) 
    {
         vector<string> ans;        
         generate(ans,"",0,0,n);
         return ans;
    }
};

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值