我在Python中使用递归需要解决一些问题。 我只是递归不好,不知道如何开始,所以请指导我。
如果字符串仅包含字符'(',')'并且可以以数学公式的方式写成这样的括号序列,那么我们将说一个字符串包含'n'个合法的括号对,括号的每次打开都会关闭,并且括号在打开之前不会关闭)。描述它的更精确方法是在字符串的开头,'('大于或等于')'的数目-整个字符串中任何类型的char的数目都相等。实现一个函数,该函数接收正整数n并返回一个列表,该列表包含括号中n组合的每个合法字符串。
我至少已经开始尝试,考虑了一个基本案例,但是我的基本案例到底是什么?
当给定最小n为1时,我试图考虑一个基本情况,然后我想我必须返回一个列表['(',')']。但是要做到这一点我也有困难...
1 2 3 4
1 2 3
1 2
1
请向我解释递归解决问题的方法。
谢谢!
答案 0 :(得分:2)
看一个简单的问题案例可能会有所帮助:
n = 2
(())
()()
因此,我们从n=2
开始,我们先产生(
次n次序列,然后再产生)
次n次序列,然后返回其列表。然后,我们以n-1递归地执行该操作。当我们到达n=1
时,就好像到达了基本情况一样,就是我们需要返回一个()
n次的字符串(不是n = 1而是n = 2)。
n = 3
((()))
(())()
()()()
与n=3
相同的模式。
以上示例有助于理解如何递归解决问题。
def legal_parentheses(n, nn=None):
if nn == 1:
return ["()" * n]
else:
if not nn:
nn = n
# This will produce n ( followed by n ) ( i.e n=2 -> (()) )
string = "".join(["(" * nn, ")" * nn])
if nn < n:
# Then here we want to produce () n-nn times.
string += "()" * (n-nn)
return [string] + legal_parentheses(n, nn-1)
print(legal_parentheses(3))
print(legal_parentheses(4))
print(legal_parentheses(5))
对于n = 3:
['((()))', '(())()', '()()()']
对于n = 4:
['(((())))', '((()))()', '(())()()', '()()()()']
对于n = 5:
['((((()))))', '(((())))()', '((()))()()', '(())()()()', '()()()()()']
这是解决问题的一种方式。
我认为,递归地解决问题的方法是首先选择您所遇到问题的最简单示例n=2
,然后写下您的期望结果。在这种情况下,您期望获得以下输出:
"(())", "()()"
现在,您正在尝试找到一种解决问题的策略,以便可以产生每个字符串。我首先考虑基本情况。我说微不足道的情况是当结果为()()
时,我知道该结果的元素只是()
的n倍。如果是n=2
,我应该期望()()
,而当n=3
我应该期望()()()
时,序列中应该只有一个这样的元素(因此应该只执行一次)因此,它成为基本情况。问题是我们如何计算结果的(())
部分。这些模式表明,我们只需要在n
后面加上(
n
,然后再加上)
(())
-> n=2
。这看起来是个不错的策略。现在,您需要开始思考一个稍微棘手的问题,看看我们的策略是否仍然有效。
因此,让我们想到n=3
。结果是什么?
'((()))', '(())()', '()()()'
好的,我们看到基本情况仍然应该产生()()()
部分,也应该产生((()))
部分。 (())()
部分呢?看来我们需要稍微不同的方法。在这种情况下,我们需要以某种方式生成n (
,然后生成n )
,然后生成n-1
(
,然后生成n-1
)
,然后n-2
(
之后是n-2
)
,依此类推,直到达到基本情况n=1
,在这里我们将只生产()
部分{ {1}}次。但是,如果我们每次用n
调用该函数,那么当我们到达基本情况时,我们不知道原始的n-1
值是什么,因此我们无法产生n
部分因为我们不知道要多少(如果原始()
是3,那么我们需要n
,但是如果我们通过用()()()
调用函数来更改n
,然后按当我们达到基本情况时,我们将不知道原始的n-1
值)。因此,因此,在我的解决方案中,我引入了一个名为n
的第二个变量,该变量每次都会减小,但仍然nn
保持不变,因此我们知道< / strong>原始值是什么。