leetcode
leetcode 2901 ~ 2950
括号生成

括号生成

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 22 ms, 内存: 16.3 MB


/*
 * 思路:使用递归来生成所有有效的括号组合。我们可以维护两个计数器:
 * 一个记录当前左括号的数量,另一个记录右括号的数量。只有当左括号数量少于 n 时,
 * 我们才可以添加左括号;只有当右括号数量少于左括号数量时,我们才可以添加右括号。
 * 使用Java Streams将结果转换成一个列表。
 */
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class GenerateParenthesesStream {
    public List<String> generateParenthesis(int n) {
        return backtrack("", 0, 0, n).collect(Collectors.toList());
    }

    private Stream<String> backtrack(String current, int open, int close, int max) {
        if (current.length() == max * 2) {
            return Stream.of(current);
        }

        Stream<String> result = Stream.empty();
        if (open < max) {
            result = Stream.concat(result, backtrack(current + "(", open + 1, close, max));
        }
        if (close < open) {
            result = Stream.concat(result, backtrack(current + ")", open, close + 1, max));
        }
        return result;
    }

    public static void main(String[] args) {
        GenerateParenthesesStream gps = new GenerateParenthesesStream();
        System.out.println(gps.generateParenthesis(3));
    }
}

解释

方法:

这个题解采用了递归加记忆化的方法来生成所有有效的括号组合。基本思路是使用深度优先搜索(DFS),递归地构建每一种可能的括号组合。对于给定的n(括号对数),函数dfs(n)返回所有由n对括号构成的有效组合。递归的基准情况是当n等于0时,只有一个有效的组合,即空字符串。对于n>0的情况,通过枚举左侧括号内包含的括号对数i(从0到n-1),然后对于每个i,计算左侧括号内的组合和右侧的组合,然后将它们组合成一个有效的括号表达式。采用记忆化是为了避免重复计算已经解决的子问题,提高效率。

时间复杂度:

O(C_n * n)

空间复杂度:

O(C_n * n)

代码细节讲解

🦆
在递归函数中,为何选择枚举左侧括号内包含的括号对数i,而不是简单地每次只添加一对括号?
选择枚举左侧括号内包含的括号对数i的原因是为了生成所有可能的有效括号组合。如果每次只简单地添加一对括号,将无法控制和保证括号的正确匹配和组合。通过枚举每个可能的i,我们可以确保左侧和右侧的括号都是有效的,从而构造出所有有效的括号字符串。这种方法可以确保每个生成的字符串都是唯一的有效组合,避免了生成无效或重复的括号组合。
🦆
记忆化存储(使用cache装饰器)具体是如何避免重复计算的,能否详细解释其工作原理?
记忆化存储通过存储已经计算的结果来避免重复计算,提高算法的效率。在本题解中,使用了Python的cache装饰器,它自动保存每次函数调用的结果。当递归函数dfs被调用时,cache首先检查是否已经计算过给定参数的结果。如果是,直接返回存储的结果,避免了再次进行相同的计算。这种方法特别适用于递归函数,因为递归过程中很多子问题会被重复计算。通过记忆化,我们可以显著减少计算量,尤其是在处理大量数据时。
🦆
题解中提到的Catalan数与此问题有何关联,能否详细解释Catalan数在此算法中的作用和意义?
Catalan数是一系列自然数,它们在各种计数问题中非常重要,包括括号匹配问题。在括号生成问题中,第n个Catalan数表示n对括号可以形成的不同有效括号组合的数量。算法中使用递归来构造所有有效的括号组合,而Catalan数提供了对组合总数的理论验证。具体来说,Catalan数的递推公式 C(n) = Σ(i=0到n-1)C(i) * C(n-1-i),与我们在递归算法中使用的括号内外分配方法非常吻合,其中每个C(i)代表左侧i对括号的有效组合数,C(n-1-i)代表右侧对应括号的有效组合数。因此,Catalan数不仅预示了结果的数量,还与算法的结构密切相关。

相关问题