• LeetCode 22. Generate Parentheses


    问题链接

    LeetCode 22. Generate Parentheses

    题目解析

    括号匹配问题:给出数字n,求n对括号所有可能的匹配形式。

    解题思路

    明显使用递归的方法求解,最初的想法是利用两个变量 (left)(right) 记录剩余可使用的左右括号数,当 (left>right) 时,不可能匹配,直接返回;当 (left=right=0) 时,代表匹配完毕;否则,根据 left 和 right 的剩余数量分别递归调用。

    参考代码

    class Solution {
    public:
        vector<string> generateParenthesis(int n) {
            vector<string> res;
            string ans = "";
            DFS(n, n, ans, res);
            return res;
        }
        void DFS(int left, int right, string ans, vector<string> &res) {
            if(left > right) return;
            if(left == 0 && right == 0)
                res.push_back(ans);
            else {
                if(left > 0) DFS(left-1, right, ans+"(", res);
                if(right > 0) DFS(left, right-1, ans+")", res);
            }
        }
    };
    

    改进

    提交之后确实可以AC,但是发现需要4ms,只能打败40%左右的提交,说明不是很好,仔细想想发现是剪枝不够。如果 left=0,即左括号已经用尽,此时直接添加右括号即可,不需要再递归求解,这样可以减少不少的开销。

    代码做了稍微的调整,left 和 right的值定义为已经使用的左右括号数。提交之后大约3ms,可打败95%以上的提交,足够了,参考代码如下:

    class Solution {
    public:
        vector<string> generateParenthesis(int n) {
            vector<string> res;
            string ans = "";
            DFS(n, 0, 0, ans, res);
            return res;
        }
        void DFS(int n, int left, int right, string ans, vector<string> &res) {
            if(left < right) return;
            if(left == n) {
                for(int i=0; i < left-right; i++)
                    ans = ans+")";
                res.push_back(ans);
            }
            else {
                if(left < n) DFS(n, left+1, right, ans+"(", res);
                if(right < n) DFS(n, left, right+1, ans+")", res);
            }
        }
    };
    

    哦对了,上面这段代码还可以简短一点,效果是一样的,参考代码如下:

    class Solution {
    public:
        vector<string> generateParenthesis(int n) {
            vector<string> res;
            string ans = "";
            DFS(n, 0, 0, ans, res);
            return res;
        }
        void DFS(int n, int left, int right, string ans, vector<string> &res) {
            if(left+right == 2*n) {
                res.push_back(ans);
                return;
            }
            if(left < n) DFS(n, left+1, right, ans+"(", res);
            if(right < left) DFS(n, left, right+1, ans+")", res);
        }
    };
    

    时间复杂度

    这里的时间复杂度计算起来有些麻烦,参考官方题解:https://leetcode.com/problems/generate-parentheses/solution/


    LeetCode All in One题解汇总(持续更新中...)

    本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


  • 相关阅读:
    UVA 11995
    LA 5031
    防卫导弹
    跳马问题
    UVA 11992
    POJ 3264 Balanced Lineup
    0-1背包
    石子合并
    小技巧
    Android广播中有序和无序的区别
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8630260.html
Copyright © 2020-2023  润新知