permutations-why do we need to return copy of the list from local function?

174 Views Asked by At

I'm writing a permutation function as below, what I'm confused is if we return "res.append(nums[:])", it works perfectly, but if we return just "res.append(nums)", it'll only return the original nums value, without storing the new nums after my manipulation... But not sure about the theory behind it, could anybody explain? Thanks!


https://leetcode.com/problems/permutations/

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        if len(nums)==0:
            return [[]]
        res=[]
    
    
        def get_permute(n):
            if n==0:
                res.append(nums[:]) ##<----here if we do res.append(nums) it'll be wrong, but why?
                return
            for i in range(n+1):
                nums[i], nums[n]=nums[n], nums[i]
                get_permute(n-1)
                nums[n], nums[i]=nums[i], nums[n]
    
        get_permute(len(nums)-1)
        return res
2

There are 2 best solutions below

0
Samwise On

When you take a slice of a list (even if it's the entire list, i.e. [:]), a new list is created.

So if you do res.append(nums) you're appending a reference to the original nums list, and if nums changes in the future, then you'll see that in res.

When you do res.append(nums[:]) you're taking a snapshot of the current contents of nums and appending that to res -- now even if nums changes later, res will not.

0
gelonida On

shortly:

nums[:] creates a copy of nums. So with: res.append(nums[:]) you maker sure, that what can be accessed by iterating through res will not be changed even if nums is modified lateron.

Just look at following mini example:

nums = [1, 2, 3]
res = []
res.append(nums)
res.append(nums[:])
print(res)
nums.append(4)
print(res)

The output will be

[[1, 2, 3], [1, 2, 3]]
[[1, 2, 3, 4], [1, 2, 3]]