• leetcode:22. 括号生成


    22. 括号生成

    来源:力扣(LeetCode)

    链接: https://leetcode.cn/problems/generate-parentheses/

    数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

    示例 1:

    输入:n = 3
    输出:["((()))","(()())","(())()","()(())","()()()"]
    
    • 1
    • 2

    示例 2:

    输入:n = 1
    输出:["()"]
    
    • 1
    • 2

    提示:

    • 1 <= n <= 8

    解法

    • 生成所有组合之后再判断是否合法:先使用递归生成所有的可能扩号组合,之后再去判断每种括号组合是否合法;
    • 基于括号的关系,能够在生成括号的同时就能知道是否是合法组合:括号对的个数为n,则左括号的个数也是n个,左括号随时都能放进去,只要左括号的个数不超过n个,而右括号需要考虑一下左括号的个数,当右括号的个数小于左括号的时候,是可以放进去的,另外,右括号也不能超过n个。但由于左括号是不大于n的,所以右括号小于等于左括号个数的时候 已经满足这个限制了。
    • 用括号与n-1的结果进行任何组合 : 其中n递归到1; 然后将’()'放到n-1结果中任何一个位置即可,进行字符串拼接;

    代码实现

    先递归生成所有组合,再去判断合法性

    python实现

    class Solution:
        def generateParenthesis(self, n: int) -> List[str]:
            ans = []
    
            # 先生成所有可能的组合,并对每种组合进行判断是否符合标准
            def helper(ss=[]):
                if len(ss) == 2*n:
                    if self.valid(''.join(ss)):
                        ans.append(''.join(ss))
                else:
                    ss.append('(')
                    helper(ss)
                    ss.pop()
                    ss.append(')')
                    helper(ss)
                    ss.pop()
            
            helper()
            return ans
        
        def valid(self, s):
            counts = 0
            for char in s:
                if char == '(':
                    counts += 1
                else:
                    counts -= 1
    
                if counts < 0:
                    return False
            return counts == 0 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    c++实现

    class Solution {
    private:
        vector<string> ans;
    
    public:
        bool valid(string s) {
            int counts = 0;
            for(char ch: s) {
                if (ch == '(')
                    counts++;
                else
                    counts--;
                if (counts < 0)
                    return false;
            }
            return counts == 0;
        }
    
        string convert(vector<char> cs, int size) {
            string s;
            for(int i=0; i<size; i++)
                s += cs[i];
            return s;
        }
    
        void _generateParenthesis(vector<char> cs, int n) {
            if (cs.size() == 2 * n) {
                string s = convert(cs, 2*n);
                if (valid(s))
                    ans.push_back(s);
            }
            else {
                cs.push_back('(');
                _generateParenthesis(cs, n);
                cs.pop_back();
                cs.push_back(')');
                _generateParenthesis(cs, n);
                cs.pop_back();
            }
        }
    
        vector<string> generateParenthesis(int n) {
            _generateParenthesis({}, n);
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    复杂度分析

    • 时间复杂度: O ( 2 2 n ∗ n ) O(2^{2n} * n) O(22nn)
    • 空间复杂度: O ( n ) O(n) O(n)

    递归生成的同时基于左右括号数量关系进行组合删减

    python实现

    class Solution:
        def generateParenthesis(self, n: int) -> List[str]:
            ans = []
    
            def helper(l, r, s):
                # 递归结束条件
                if len(s) == 2*n:
                    ans.append(s)
                
                if len(s) > 2 * n:
                    return
                
                # 开始处理
                if l < n:
                    helper(l+1, r, s+'(')
                if r < l and r < n:
                    helper(l, r+1, s+')')
            
            helper(0, 0, '')
            return ans
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    c++实现

    class Solution {
    private:
        vector<string> ans;
    
    public:
        int _generateParenthesis(int left, int right, int n, string s) {
            if (s.size() == 2 * n)
                ans.push_back(s);
            
            if (s.size() > 2*n)
                return -1;
    
            if (left < n)
                _generateParenthesis(left+1, right, n, s+'(');
            if (right < left)
                _generateParenthesis(left, right+1, n, s+')');
            return 0;
        }
    
        vector<string> generateParenthesis(int n) {
            _generateParenthesis(0, 0, n, "");
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    复杂度分析
    在这里插入图片描述

    "()"与n-1结果的任意字符串拼接

    python实现

    class Solution:
        def generateParenthesis(self, n: int) -> List[str]:
            if n == 1:
                return ['()']
            
            res = set()
            
            for i in self.generateParenthesis(n-1):
                for j in range(len(i)+2):
                    res.add(i[0:j] + '()' + i[j:])
            return list(res)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    c++实现

    class Solution {
    public:
        vector<string> generateParenthesis(int n) {
            if (n==1)
                return {"()"};
            
            unordered_map<string, int> mp;
            vector<string> res;
    
            string tmp;
            for (auto& s: generateParenthesis(n-1)) {
                for (int i=0; i < 2*(n-1); i++) {
                    tmp = s.substr(0, i) + "()" + s.substr(i, 2*(n-1));
                    if (mp[tmp] == 0) {
                        ++mp[tmp];
                        res.push_back(tmp);
                    }
                }
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    复杂度分析
    在这里插入图片描述

  • 相关阅读:
    HBase 开发:使用Java操作HBase 第1关:创建表
    文本生成图像T2I复现所需操作命令合集
    Qt源码解析-源码解析-QVideoWidget播放手机视频旋转问题
    Zabbix出现 404Not FoundThe requested URL /zabbix was not found on this server.
    前端:css中的多列的实现与介绍
    如何将vue-element-admin中的excel导入导出功能模块, 单独拿出来用 更新中...
    Go语言学习(七)-- 方法和接口
    [springMVC学习]12、异常处理
    [附源码]java毕业设计在线购物商城
    grafana使用小结
  • 原文地址:https://blog.csdn.net/uncle_ll/article/details/125472066