生成括号问题的闭包数法
Closure Number Method for Generate Parenthesis Problem
Leetcode上的Generate Parenthesis标准题如下
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:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
他们在解决方案选项卡中解释了 Closure Number Method,我觉得这很难理解。
我对代码进行了干练 运行,甚至得到了正确答案,但似乎无法理解它为什么有效?这种方法背后的直觉是什么?
如有任何帮助,我们将不胜感激!
该算法的基本思想是动态规划。因此,您尝试 将您的问题分解为易于解决的较小问题 。在此示例中,您将 sub-problems 设置得非常小,以至于解决方案要么是空字符串(如果大小为 0),要么解决方案是“()”(对于大小 1)。
您开始使用这样的知识:如果您想要给定长度的括号,那么 第一个字符需要是“(”,并且在字符串后面的某个位置需要这个字符: ")"。否则输出无效。
现在您不知道右括号的位置,所以您只需尝试每个位置(第一个 for 循环)。
你知道的第二件事是,在左括号和右括号之间以及右括号之后必须有一些东西,你真的不知道它看起来如何(因为有很多可能性),但是它 必须再次成为有效的括号对 。
现在这个问题正是您已经解决的问题。因此,您只需放入有效括号的所有可能性(使用较小的输入大小)。因为这正是您的算法已经执行的操作,您可以使用递归函数调用来执行此操作。
如此总结:你知道问题的一部分,剩下的问题就是同一个问题,只是规模小了点。所以你解决了你知道的问题的一小部分,并递归地调用相同的方法来解决问题的其余部分。之后你只需将它们放在一起并得到你的解决方案。
动态编程通常不是那么容易理解但非常强大。因此,如果您不直接理解它,请不要担心。解决这样的难题是学习动态规划的最好方法。
一个序列的闭包数,其大小为序列的最小前缀,它本身就是一个有效序列。
如果一个序列的闭包号为 k,那么您知道在索引 0 中有 '(',在索引 k 中有 ')'
该方法通过检查此类前缀的所有可能大小来解决问题,对于每个前缀,它将序列打断为前缀(删除 0 和 k 元素)和序列的所有其余部分,并递归地解决两个子问题。
Leetcode上的Generate Parenthesis标准题如下
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:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
他们在解决方案选项卡中解释了 Closure Number Method,我觉得这很难理解。
我对代码进行了干练 运行,甚至得到了正确答案,但似乎无法理解它为什么有效?这种方法背后的直觉是什么?
如有任何帮助,我们将不胜感激!
该算法的基本思想是动态规划。因此,您尝试 将您的问题分解为易于解决的较小问题 。在此示例中,您将 sub-problems 设置得非常小,以至于解决方案要么是空字符串(如果大小为 0),要么解决方案是“()”(对于大小 1)。
您开始使用这样的知识:如果您想要给定长度的括号,那么 第一个字符需要是“(”,并且在字符串后面的某个位置需要这个字符: ")"。否则输出无效。
现在您不知道右括号的位置,所以您只需尝试每个位置(第一个 for 循环)。
你知道的第二件事是,在左括号和右括号之间以及右括号之后必须有一些东西,你真的不知道它看起来如何(因为有很多可能性),但是它 必须再次成为有效的括号对 。
现在这个问题正是您已经解决的问题。因此,您只需放入有效括号的所有可能性(使用较小的输入大小)。因为这正是您的算法已经执行的操作,您可以使用递归函数调用来执行此操作。
如此总结:你知道问题的一部分,剩下的问题就是同一个问题,只是规模小了点。所以你解决了你知道的问题的一小部分,并递归地调用相同的方法来解决问题的其余部分。之后你只需将它们放在一起并得到你的解决方案。
动态编程通常不是那么容易理解但非常强大。因此,如果您不直接理解它,请不要担心。解决这样的难题是学习动态规划的最好方法。
一个序列的闭包数,其大小为序列的最小前缀,它本身就是一个有效序列。 如果一个序列的闭包号为 k,那么您知道在索引 0 中有 '(',在索引 k 中有 ')' 该方法通过检查此类前缀的所有可能大小来解决问题,对于每个前缀,它将序列打断为前缀(删除 0 和 k 元素)和序列的所有其余部分,并递归地解决两个子问题。