LeetCode 22 Generate Parentheses (Tag:Sting Difficulty:Medium)

293 阅读2分钟

这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

前言

关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!

题目描述

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

有效括号组合需满足:左括号必须以正确的顺序闭合。

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

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

链接:leetcode-cn.com/problems/ge…

题解

这道题意思是给定一个 n,代表左括号和右括号的个数,我们需要用这些左括号和右括号来构造出所有合理的括号对,合理的括号对的特点是左括号比右括号早出现,不能存在单独右括号先出现。

基于题意,首先想到的就是 dfs + 回溯 的方法。我们用 right 和 left 代表剩余可选的右括号和左括号数量。递归终止条件就是 right === left === 0, 这时表示我们找到了一个答案。

递归过程是括号生成的过程。可以肯定的是,左括号在没用完的情况下,是可以一直添加的,而右括号在可用数量高于左括号时,是不能添加的。因此有两个递归路径:一条是在 left > 0 的情况下,我们一直添加左括号,第二条递归路径时,当 right < left,即已经有足够的左括号在前面的情况下,我们可以添加右括号。当然,在每次添加完之后要记得回溯,将 curr 恢复原状。

具体代码如下,时间复杂度为 O(2^n)

/**
 * @param {number} n
 * @return {string[]}
 */
var generateParenthesis = function(n) {
  let ans = []
  let curr = []
  dfs(curr, n, n, ans)
  return ans
};

var dfs = (curr, right, left, ans) => {
    if (right === 0 && left === 0) {
        ans.push(curr.join(''))
        return
    }
    if (right > 0) {
      curr.push('(')
      dfs(curr, right - 1, left, ans)
      curr.pop()
    } 
  
    if (right < left) {
      curr.push(')')
      dfs(curr, right, left - 1, ans)
      curr.pop()
    } 
}