22. 括号生成

967 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

也是很久没做这种题了。第一秒甚至没反应过来。

题目描述

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

image.png

思路分析

最开始拿到这道题难免会去往栈那方面想,因为感觉是一个所有括号可能的遍历再加上对每一种可能判断其合法性。

但这样算粗略的估计一下时间复杂度会比较高,突然发现参数只有一个int型n,那么其实从某种角度说,可能的状况是可以被“算”出来的,虽然现在没有一个已知的公式可以用,但我们马上想到,对于n=2,只有可能在n=1的基础上,左边加一下,外边加一下,所以这道题其实是一个动态规划。

那么!难点来了

随着n的增加,可能性也更复杂,后面的状态转移方程怎么求呢?

冷静!这个也并不是求数,所以对于n=3时,我们可以将他分为给n=2外面加括号(两种可能),给一个n=1加括号(前后两种可能)以及并列(一种)。

也就是分为

  • 2',0(但2有两种形态)
  • 1',1
  • 1,1'
  • 2,0'

(这个有点抽象,但我希望你可以明白)

不过实际上复杂度并不低,因此看了下执行用时为 0 ms 的范例,惊为天人

class Solution { 
    public: 
    vector<string> generateParenthesis(int n) { 
        vector<string> result; generate("", n, n, result); 
        return result; 
    } 
    private: 
    void generate(string item, int left, int right, vector<string>& result){ 
        if(left == 0 && right == 0){ 
            result.push_back(item); 
            return;
        } 
        if(left > 0){
            generate(item + '(', left - 1, right, result);
        } 
        if(left < right){ 
            generate(item + ')', left, right - 1, result); 
        } 
    } 
};