I was trying to build a solution to the problem of generating all possible combination of k
of the length n
ex: k = 4, n = 2
output :
[1, 1]
[1, 2]
[1, 3]
[1, 4]
[2, 1]
[2, 2]
[2, 3]
[2, 4]
[3, 1]
[3, 2]
[3, 3]
[3, 4]
[4, 1]
[4, 2]
[4, 3]
[4, 4]
Here is the pseudocode for the logic that I implemented
def backTrack(arr):
if length(arr) == k:
return
loop through from 1 to n <- for i in range(1, n+1):
i = value of loop
add i to an array variable arr <- arr.append(i)
backtrack(arr) <- recurse
remove last index value from arr <- arr = arr[:-1]
for this above code, I am supposed to get the following values
on depth 1:
the loop starts with 1
and arr = [1]
then it recuses to depth 2
the loop starts with 1
and arr = [1, 1]
since the length of arr = k =2 it wont recurse further and continue
arr = arr[:-1] = arr = [1]
then i will be 2
and arr = [1,2]
similarly [1, 3] and [1, 4] and then it goes to depth 1 or the parent call
on depth 1
value of i = 1
and arr = 1
now, arr = arr[:-1] that makes arr = []
and now i becomes 2 and the process continues
But debugging the code written with the following pseudo code, shows that on depth 1
the arr never get back to being [1]
but become [1, 1]
I am still struggling to understand why it is so.
Below is the debugging solution with the print statements
class Solution(object):
def combine(self, n, k):
def backTrack(arr, result, depth):
if len(arr) == k:
return
for i in range(1, n + 1):
arr.append(i)
print("depth = " + str(depth) + ", i = " + str(i) + ", arr=" + str(arr))
backTrack(arr, result, depth + 1)
print("depth -> " + str(depth) + ", i-> " + str(i) + ", arr-> " + str(arr))
arr = arr[:-1]
return backTrack([], [], 1)
ob = Solution()
result = ob.combine(4, 2)
Below is the debugged output
depth = 1, i = 1, arr=[1]
depth = 2, i = 1, arr=[1, 1]
depth -> 2, i-> 1, arr-> [1, 1]
depth = 2, i = 2, arr=[1, 2]
depth -> 2, i-> 2, arr-> [1, 2]
depth = 2, i = 3, arr=[1, 3]
depth -> 2, i-> 3, arr-> [1, 3]
depth = 2, i = 4, arr=[1, 4]
depth -> 2, i-> 4, arr-> [1, 4]
depth -> 1, i-> 1, arr-> [1, 1] * going back to parent call arr never becomes 1
depth = 1, i = 2, arr=[1, 2]
depth -> 1, i-> 2, arr-> [1, 2]
depth = 1, i = 3, arr=[1, 3]
depth -> 1, i-> 3, arr-> [1, 3]
depth = 1, i = 4, arr=[1, 4]
depth -> 1, i-> 4, arr-> [1, 4]
I have marked the debugger output in *
to show the state of the arr in the parent call never gets back to being 1
I want to understand why it is so.
arr = arr[:-1]
creates a new copy of arr
with the last element removed and assigns it to the local variable arr
. This means that the arr
s in other scopes of the recursive calls reference some other list which still has the last element.
You need to remove the last element from this list by writing arr.pop()
.
If you need further explanation about mutable and immutables in python and why it works this way please comment.