zoukankan      html  css  js  c++  java
  • [Swift]LeetCode22. 括号生成 | Generate Parentheses

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/9890477.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

    For example, given n = 3, a solution set is:

    [
      "((()))",
      "(()())",
      "(())()",
      "()(())",
      "()()()"
    ]

    给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

    例如,给出 = 3,生成结果为:

    [
      "((()))",
      "(()())",
      "(())()",
      "()(())",
      "()()()"
    ]

    【回溯法】 思路和算法

    只有在我们知道序列仍然保持有效时才添加 '(' or ')',而不是像方法一那样每次添加。我们可以通过跟踪到目前为止放置的左括号和右括号的数目来做到这一点,

    如果我们还剩一个位置,我们可以开始放一个左括号。 如果它不超过左括号的数量,我们可以放一个右括号。

     1 class Solution {
     2     func generateParenthesis(_ n: Int) -> [String] {
     3         var ans:[String] = [String]()
     4         backtrack(&ans, "", 0, 0, n)
     5         return ans
     6     }
     7     
     8     func backtrack(_ ans: inout [String], _ cur:String, _ open:Int, _ close:Int, _ max:Int)
     9     {
    10         if cur.count == max * 2
    11         {
    12             ans.append(cur)
    13             return
    14         }
    15         if open < max
    16         {
    17             backtrack(&ans, cur+"(", open+1, close, max)
    18         }
    19         if close < open
    20         {
    21             backtrack(&ans, cur+")", open, close+1, max)
    22         }
    23     }
    24 }

    【闭合数】思路

    为了枚举某些内容,我们通常希望将其表示为更容易计算的不相交子集的总和。

    考虑有效括号序列 S 的闭包数:至少存在index> = 0,使得 S[0], S[1], ..., S[2*index+1]是有效的。 显然,每个括号序列都有一个唯一的闭包号。 我们可以尝试单独列举它们。

    算法

    对于每个闭合数 c,我们知道起始和结束括号必定位于索引 0 和 2*c + 1。然后两者间的 2*c 个元素一定是有效序列,其余元素一定是有效序列。

     1 class Solution {
     2     func generateParenthesis(_ n: Int) -> [String] {
     3         var ans:[String] = [String]()
     4         if n == 0
     5         {
     6             ans.append("")
     7         }
     8         else
     9         {
    10             for c in 0..<n
    11             {
    12                 for left in generateParenthesis(c)
    13                 {
    14                     for right in generateParenthesis(n-1-c)
    15                     {
    16                         ans.append("(" + left + ")" + right)
    17                     }
    18                 }
    19             }
    20         }
    21         return ans
    22     }
    23 }

     8ms

     1 class Solution {
     2     func generateParenthesis(_ n: Int) -> [String] {
     3         var output: [String] = []
     4         
     5         handler(output: &output, n: n, left: 0, right: 0, text: "")
     6         
     7         return output
     8     }
     9     
    10     func handler(output: inout [String], n: Int, left: Int, right: Int, text: String) {
    11         // print("left: (left), right: (right)")
    12         
    13         if(left == n && right == n) {
    14             output.append(text)
    15             return
    16         }
    17 
    18         if(left <= n && left > right) {
    19             handler(output: &output, n: n, left: left, right: right + 1, text: text + ")")
    20         }
    21         
    22         if(left < n) {
    23             handler(output: &output, n: n, left: left + 1, right: right, text: text + "(")
    24         }
    25         
    26     }
    27 }

    12ms

     1 class Solution {
     2     func generateParenthesis(_ n: Int) -> [String] {
     3         var ss = [String]()
     4         generate(ss: &ss, s: "", open: 0, close: 0, n: n)
     5         return ss
     6     }
     7 
     8     private func generate(ss: inout [String], s: String, open: Int, close: Int, n: Int) {
     9         if s.count == n * 2 && !s.isEmpty {
    10             ss.append(s)
    11         }
    12         if open < n {
    13             generate(ss: &ss, s: "(s)(", open: open+1, close: close, n: n)
    14         }
    15         if close < open {
    16             generate(ss: &ss, s: "(s))", open: open, close: close+1, n: n)
    17         }
    18     }
    19 }

    12ms

     1 class Solution {
     2     func generateParenthesis(_ n: Int) -> [String] {
     3         guard n > 0 else {
     4             return []
     5         }
     6         var result = [String]()
     7         
     8         dfs(left: 0, right: 0, buffer: "", result: &result, n: n)
     9         
    10         return result
    11     }
    12 
    13     func dfs(left: Int, right: Int, buffer: String, result: inout [String], n: Int) {
    14         if left == n && right == n {
    15             result.append(buffer)
    16             return
    17         }
    18         
    19         if left < n {
    20             dfs(left: left + 1, right: right, buffer: buffer + "(", result: &result, n: n)
    21         }
    22         
    23         if left > right {
    24             dfs(left: left, right: right + 1, buffer: buffer + ")", result: &result, n: n)
    25         }
    26     }
    27 }

    20ms

     1 class Solution {
     2     func generateParenthesis(_ n: Int) -> [String] {//闭合数
     3         return generateBracket(n)
     4     }
     5 
     6     func generateBracket(_ n: Int) -> [String] {
     7         if n <= 0 {
     8             return [""]
     9         }
    10         
    11 
    12         var bracket : [String] = []
    13         
    14         for idx in 0..<n {
    15             for left in generateBracket(idx) {
    16                 for right in generateBracket(n-idx-1) {
    17                     bracket.append("((left))(right)")
    18                 }
    19             }
    20         }
    21         
    22         return bracket
    23     }
    24 }

    24ms

     1 class Solution {
     2     func generateParenthesis(_ n: Int) -> [String] {
     3         if n == 0 {return []}
     4         return dfs("",  n, n)
     5     }
     6 
     7     //遍历叶子节点
     8     func dfs(_ head:String, _ left:Int, _ right:Int) -> [String] {
     9         if left == 0 && right == 0 { 
    10             return [head] 
    11         }
    12         var res = [String]()
    13         if left > 0 {   
    14             res = res + dfs(head + "(", left-1, right) 
    15         }
    16         if right > left  { 
    17             res = res + dfs(head + ")", left, right-1) 
    18         }
    19         return res
    20     }
    21 }

    44ms

     1 class Solution {
     2 enum Paren: String {
     3   case o = "("
     4   case c = ")"
     5 }
     6 
     7 class TreeNode {
     8   let val: Paren
     9   var left: TreeNode?
    10   var right: TreeNode?
    11   
    12   init(val: Paren) {
    13     self.val = val
    14   }
    15   
    16   func treeValues() -> [String] {
    17     // DFS walk the tree multiple times to print out the tree
    18     guard (self.left != nil) || (self.right != nil) else {
    19       return [self.val.rawValue]
    20     }
    21     
    22     var res = [String]()
    23     for node in [self.left, self.right] {
    24       if let node = node {
    25         for s in node.treeValues() {
    26           res.append(self.val.rawValue + s)
    27         }
    28       }
    29     }
    30     return res
    31   }
    32 }
    33 
    34 func populateTree(root: TreeNode, maxOpenParens: Int, availOpenParens: Int, availClosedParens: Int) {
    35   // Implement a BST
    36   if availOpenParens > 0 { 
    37     root.left = TreeNode(val: Paren.o)
    38     populateTree(root: root.left!, maxOpenParens: maxOpenParens, availOpenParens: availOpenParens - 1, availClosedParens: availClosedParens + 1)
    39   }
    40   if availClosedParens > 0 { 
    41     root.right = TreeNode(val: Paren.c)
    42     populateTree(root: root.right!, maxOpenParens: maxOpenParens, availOpenParens: availOpenParens, availClosedParens: availClosedParens - 1)
    43   }
    44 }
    45 
    46 func generateParenthesis(_ n: Int) -> [String] {
    47     let root = TreeNode(val: Paren.o)
    48     populateTree(root: root, maxOpenParens: n, availOpenParens: n - 1, availClosedParens: 1)
    49     return root.treeValues()
    50   }
    51 }
     
  • 相关阅读:
    一个程序员的职业规划
    基于Andoird 4.2.2的Account Manager源代码分析学习:创建选定类型的系统帐号
    [置顶] C++学习书单
    js快速分享代码
    The declared package does not match the expected package
    IBM Rational Appscan Part 1
    IBM Rational Appscan: Part 2 ---reference
    阅读redis源代码的一些体会
    18 Command Line Tools to Monitor Linux Performance
    代码规范
  • 原文地址:https://www.cnblogs.com/strengthen/p/9890477.html
Copyright © 2011-2022 走看看