-1

I have some problem to solve using recursion in Python. I'm simply bad in recursion and don't know how to start so please guide me.

We will say that a string contains 'n' legal pairs of parentheses if the string contains only the chars '(',')' and if this sequence of parentheses can be written so in a manner of mathematical formula (That is, every opening of parentheses is closed and parentheses are not closed before they are opened). More precise way to describe it is at the beginning of the string the number of '(' is greater or equal to ')' - and the number of any kind of char in the whole string is equal. Implement a function that recieves a positive integer n and returns a list which contains every legal string of n-combination of the parentheses.

I have tried to start at least, think of a base case, but what's my base case at all?

I tried to think of a base case when I am given the minimal n which is 1 and then I think I have to return a list ['(', ')']. But to do that I have also a difficulty...

def parentheses(n):
    if n == 1:
        return combine_parent(n)

def combine_parent(n):
    parenth_lst = []
    for i in range(n):
        parenth_lst +=

Please explain me the way to solve problems recursively.

Thank you!

HelpMe
  • 91
  • 10
  • Is it a requirement to solve it using recursion? – Rafael Dec 05 '18 at 08:47
  • There seems to be a grammatical mistake in the following sentence: `Implement a function that recieves a positive integer n and returns a list with the all strings with 'n' legal pairs of parentheses.`. "with the all strings" is bugging me, and it describes the objective of the function so it is hard to help you. – hyamanieu Dec 05 '18 at 08:49
  • Rephrasing it would help. "the" followed by "all" is strange, unless "all" is attached to an adjective like in "all-seeing". – hyamanieu Dec 05 '18 at 08:55
  • 1
    Yes, the requirement is to solve that recursively. @Wli a list which contains every legal string of combination of the parentheses. Help me to think step by step recursively. – HelpMe Dec 05 '18 at 08:57
  • I have provided you with an answer, have a look and let me know if that solved your problem. – Rafael Dec 05 '18 at 09:18

1 Answers1

2

Maybe it's helpful to look in a simple case of the problem:

n = 2
(())
()()

So we start by n=2 and we produce a sequence of ( n times followed by a sequence of ) n times and we return a list of that. Then we recursively do that with n-1. When we reach n=1 it looks like we reached the base case which is that we need to return a string with () n times (not n=1 but n=2).

n = 3
((()))
(())()
()()()

Same pattern for n=3.

The above examples are helpful to understand how the problem can be solved recursively.

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))

For n = 3:

['((()))', '(())()', '()()()']

For n = 4:

['(((())))', '((()))()', '(())()()', '()()()()']

For n = 5:

['((((()))))', '(((())))()', '((()))()()', '(())()()()', '()()()()()']

This is one way of solving the problem.

The way to think about solving a problem recursively, in my opinion, is to first pick the simplest example of your problem in your case, n=2 and then write down what do you expect as a result. In this case, you are expecting the following output:

"(())", "()()"

Now, you are trying to find a strategy to break down the problem such that you can produce each of the strings. I start by thinking of the base case. I say the trivial case is when the result is ()(), I know that an element of that result is just () n times. If n=2, I should expect ()() and when n=3 I should expect ()()() and there should be only one such element in the sequence (so it should be done only once) hence it becomes the base case. The question is how do we calculate the (()) part of the result. The patterns shows that we just have to put n ( followed by n ) -> (()) for n=2. This looks like a good strategy. Now you need to start thinking for a slightly harder problem and see if our strategy still holds.

So let's think of n=3. What do we expect as a result?

'((()))', '(())()', '()()()'

Ok, we see that the base case should still produce the ()()() part, all good, and should also produce the ((())) part. What about the (())() part? It looks like we need a slightly different approach. In this case, we need to somehow generate n ( followed by n ) and then produce n-1 ( followed by n-1 ) and then n-2 ( followed by n-2 ) and so on, until we reach the base case n=1 where we just going to produce () part n times. But, if we were to call the function each time with n-1 then when we reach the base case we have no clue what the original n value was and hence we cannot produce the () part as we don't know how many we want (if original n was 3 then we need ()()() but if we change n by calling the function with n-1 then by the time we reach the base case, we won't know the original n value). Hence, because of that, in my solution, I introduce a second variable called nn that is the one that is reduced each time, but still, we leave the n unmodified so we know what the original value was.

Rafael
  • 7,002
  • 5
  • 43
  • 52
  • I didn't understand the role of 'nn' and its effect actually. It's hard to explain the difficulty with recursion. When I start thinking of solving recursively some problem, I can't imagine in my head the functionality in every recursive call, maybe something goes wrong, etc... – HelpMe Dec 05 '18 at 09:52
  • @HelpMe I updated my answer with explanation, I hope will make things more clear. – Rafael Dec 05 '18 at 21:54