1
class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        ans = []
        def backtrack(S, left, right):
            if len(S) == 2 * n:
                ans.append(''.join(S))
                return
            if left < n:
                S.append('(')
                backtrack(S, left+1, right)
                S.pop()
            if right < left:
                S.append(')')
                backtrack(S, left, right+1)
                S.pop()

        backtrack([], 0, 0)
        return ans

I am new to algorithms, and this is leetcode #22.

I don't understand why S.pop() is needed in the last line of the function here? I think when I backtrack to the previous function, the value S will be the value in the previous function, so there is no need to write S.pop() at the end of this function? as it only changes value of S in this function, not in the previous one?

But in practice, when I returned to the previous function, the change in S's value still remains? But I thought when I enter a new function a new local copy should be created? So is S's value shared in all generateParenthesis function?

R__
  • 87
  • 5
  • 1
    `S` is a list, and lists are mutable in Python – Marat Aug 08 '22 at 18:00
  • @Marat My point is, when I feed `S` as an argument into the backtrack function, I expected when I returned from the function, `S` should be unchanged. Because I think when I fed it into the function as an argument, a local variable should be created inside this function's scope. – R__ Aug 08 '22 at 18:05
  • What I'm saying is: by design, Python doesn't create a new variable in this case – Marat Aug 08 '22 at 18:06
  • *NOTHING* in Python ever implicitly makes a copy of anything. You have to explicitly request that if wanted - either a `.copy()` method, a complete slice (`X[:]`), or something from the `copy` module. – jasonharper Aug 08 '22 at 18:13
  • @jasonharper, so if I changed the value of an object inside a function, its value will be changed outside the function? – R__ Aug 08 '22 at 18:15
  • @LangREN changes to any of properties/data of the said object will perpetuate through the call stack. Assigning a whole new value to the parameter variable (`S = []`), however, will not. – Marat Aug 08 '22 at 18:27
  • @Marat Thank you! this is very tricky. Where can I find the information of this? – R__ Aug 08 '22 at 18:31
  • @LangREN Passing variables to function calls is [no different](https://docs.python.org/3/glossary.html#term-argument) then just assigning a local variable in function scope. The actual difference comes from distinction between [mutable and immutable](https://docs.python.org/3/glossary.html#term-immutable) types. – Marat Aug 08 '22 at 18:42
  • @Marat Could you please explain the assignment situation more detailedly? Do you mean if I assign a new value to the list `S` in a function, after returning from this function, the value of `S` will return to its previous value? – R__ Aug 11 '22 at 21:35
  • 1
    @LangREN Consider this code: `a = [1,2,3]; b=a; b[0]=0`. Once executed, `a` will contain `[0, 2, 3]` as as both `a` and `b` refer to the same object. Now, consider `a=[1,2,3]; b=a; b=[0, 2, 3]`. This time, `a` is not changed as the last assignment makes `b` to refer a different object – Marat Aug 11 '22 at 22:00

1 Answers1

0

Yes. Because you pass S in the backtrack function and the internal calling function (backtrack(S, left+1, right) and backtrack(S, left, right+1)) is executed until the end.

mehrh8
  • 329
  • 2
  • 5
  • Thank you, I mean when I return from, for example, `backtrack(S, left, right+1)`, the value of `S` should be same, it shouldn't remain the change in `backtrack(S, left, right+1)` because I think when I fed `S` as an argument into `backtrack(S, left, right+1)`, a local variable would be created for that function. – R__ Aug 08 '22 at 18:07