【算法】剑指 Offer II 085. 生成匹配的括号|22. 括号生成|面试题 08.09. 括号(多语言实现)

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

剑指 Offer II 085. 生成匹配的括号|22. 括号生成|面试题 08.09. 括号

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

样例 1:

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

样例 2:

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

提示:

  • 1 <= n <= 8

分析

  • 首先想到的是全排列排列方式,然后再从中挑选满足括号规则的序列。每个字符只可能是 '(' 或者 ')' 两种选择,所以全排列的数量是 22n 个。真正有效的括号序列远远少于这个量。
  • 是否可以直接去穷举生成有效的括号序列呢?
  • 首先要判断什么样的序列是有效的括号序列?
  • 很显然,首先左右括号字符的数量应该相等。
  • 右括号一定是匹配前面某个左括号。
  • 所以只包含左右括号字符,并且从左往右看,右括号数始终小于等于左括号数,最终左右括号数相等的序列就是合理合法合规的括号序列了。

题解

java

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> ans = new ArrayList<>();

        this.dfs(n, ans, new char[n * 2], 0, 0);

        return ans;
    }

    private void dfs(int n, List<String> ans, char[] cs, int left, int right) {
        if (left == n && right == n) {
            ans.add(new String(cs));
            return;
        }

        if (left < n) {
            cs[left + right] = '(';
            dfs(n, ans, cs, left + 1, right);
        }
        if (right < left) {
            cs[left + right] = ')';
            dfs(n, ans, cs, left, right + 1);
        }
    }
}

c

#define MAX_SIZE 1430

void dfs(int n, int *returnSize, char **ans, char *cs, int left, int right) {
    if (left == n && right == n) {
        ans[(*returnSize)] = calloc((n * 2 + 1), sizeof(char));
        strcpy(ans[(*returnSize)], cs);
        ++(*returnSize);
        return;
    }

    if (left < n) {
        cs[left + right] = '(';
        dfs(n, returnSize, ans, cs, left + 1, right);
    }
    if (right < left) {
        cs[left + right] = ')';
        dfs(n, returnSize, ans, cs, left, right + 1);
    }
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
char **generateParenthesis(int n, int *returnSize) {
    *returnSize = 0;
    char **ans = malloc(MAX_SIZE * sizeof(char *));
    char *cs = calloc((n * 2 + 1), sizeof(char));
    dfs(n, returnSize, ans, cs, 0, 0);
    return ans;
}

c++

class Solution {
private:
    void dfs(int n, vector<string> &ans, string &buf, int left, int right) {
        if (left == n && right == n) {
            ans.push_back(buf);
            return;
        }

        if (left < n) {
            buf.push_back('(');
            dfs(n, ans, buf, left + 1, right);
            buf.pop_back();
        }
        if (right < left) {
            buf.push_back(')');
            dfs(n, ans, buf, left, right + 1);
            buf.pop_back();
        }
    }

public:
    vector<string> generateParenthesis(int n) {
        vector<string> ans;
        string buf;
        dfs(n, ans, buf, 0, 0);
        return ans;
    }
};

python

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        ans = []

        def dfs(s, left, right):
            if left == n and right == n:
                ans.append(''.join(s))
                return
            if left < n:
                s.append('(')
                dfs(s, left + 1, right)
                s.pop()
            if right < left:
                s.append(')')
                dfs(s, left, right + 1)
                s.pop()

        dfs([], 0, 0)
        return ans
        

go

func generateParenthesis(n int) []string {
    var ans []string

    var dfs func(cs []byte, left int, right int)
    dfs = func(cs []byte, left int, right int) {
        if left == n && right == n {
            ans = append(ans, string(cs))
            return
        }

        if left < n {
            cs[left+right] = '('
            dfs(cs, left+1, right)
        }
        if right < left {
            cs[left+right] = ')'
            dfs(cs, left, right+1)
        }
    }

    dfs(make([]byte, n*2), 0, 0)

    return ans
}

rust

impl Solution {
    pub fn generate_parenthesis(n: i32) -> Vec<String> {
        let mut ans = Vec::new();

        fn dfs(n: usize, ans: &mut Vec<String>, buf: &mut String, left: usize, right: usize) {
            if left == n && right == n {
                ans.push(buf.clone());
                return;
            }
            if left < n {
                buf.push('(');
                dfs(n, ans, buf, left + 1, right);
                buf.pop();
            }
            if right < left {
                buf.push(')');
                dfs(n, ans, buf, left, right + 1);
                buf.pop();
            }
        }

        dfs(n as usize, &mut ans, &mut String::new(), 0, 0);

        ans
    }
}

在这里插入图片描述


原题传送门:https://leetcode-cn.com/problems/IDBivT/

原题传送门:https://leetcode-cn.com/problems/generate-parentheses/

原题传送门:https://leetcode.cn/problems/bracket-lcci/


非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://developer.aliyun.com/profile/sqd6avc7qgj7y 博客原创~

相关文章
|
29天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
2月前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩分享分库分表的基因算法设计,涵盖分片键选择、水平拆分策略及基因法优化查询效率等内容,助力面试者应对大厂技术面试,提高架构设计能力。
美团面试:百亿级分片,如何设计基因算法?
|
2月前
|
算法 前端开发 Java
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
这篇文章总结了单链表的常见面试题,并提供了详细的问题分析、思路分析以及Java代码实现,包括求单链表中有效节点的个数、查找单链表中的倒数第k个节点、单链表的反转以及从尾到头打印单链表等题目。
35 1
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
|
2月前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
2月前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩在读者群中分享了关于分库分表的基因算法设计,旨在帮助大家应对一线互联网企业的面试题。文章详细介绍了分库分表的背景、分片键的设计目标和建议,以及基因法的具体应用和优缺点。通过系统化的梳理,帮助读者提升架构、设计和开发水平,顺利通过面试。
美团面试:百亿级分片,如何设计基因算法?
|
2月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
84 2
|
3月前
|
机器学习/深度学习 JavaScript 算法
面试中的网红虚拟DOM,你知多少呢?深入解读diff算法
该文章深入探讨了虚拟DOM的概念及其diff算法,解释了虚拟DOM如何最小化实际DOM的更新,以此提升web应用的性能,并详细分析了diff算法的实现机制。
|
4月前
|
算法 C++
第一周算法设计与分析 H : 括号匹配
这篇文章介绍了解决算法问题"括号匹配"的方法,通过使用栈来检查给定字符串中的括号是否合法匹配,并提供了相应的C++代码实现。
|
8天前
|
算法
基于GA遗传算法的PID控制器参数优化matlab建模与仿真
本项目基于遗传算法(GA)优化PID控制器参数,通过空间状态方程构建控制对象,自定义GA的选择、交叉、变异过程,以提高PID控制性能。与使用通用GA工具箱相比,此方法更灵活、针对性强。MATLAB2022A环境下测试,展示了GA优化前后PID控制效果的显著差异。核心代码实现了遗传算法的迭代优化过程,最终通过适应度函数评估并选择了最优PID参数,显著提升了系统响应速度和稳定性。
|
5天前
|
算法
基于WOA鲸鱼优化的购售电收益与风险评估算法matlab仿真
本研究提出了一种基于鲸鱼优化算法(WOA)的购售电收益与风险评估算法。通过将售电公司购售电收益风险计算公式作为WOA的目标函数,经过迭代优化计算出最优购电策略。实验结果表明,在迭代次数超过10次后,风险价值收益优化值达到1715.1万元的最大值。WOA还确定了中长期市场、现货市场及可再生能源等不同市场的最优购电量,验证了算法的有效性。核心程序使用MATLAB2022a实现,通过多次迭代优化,实现了售电公司收益最大化和风险最小化的目标。