1. 程式人生 > >Lintcode 15.全排列 (遞迴中進行列表append操作)

Lintcode 15.全排列 (遞迴中進行列表append操作)

描述

給定一個數字列表,返回其所有可能的排列。

你可以假設沒有重複數字。

樣例

給出一個列表[1,2,3],其全排列為:

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

1. 屬於經典的題目了,但是在使用python解決卻出現問題。先貼上程式碼:

class Solution:
    """
    @param: nums: A list of integers.
    @return: A list of permutations.
    """
    def permute(self, nums):
        # write your code here
        arr = []
        if len(nums) == 0:
            return [[]]
        elif len(nums) == 1:
            return [nums]
        else:
            self.permute_temp(nums, 0, len(nums)-1, arr)
            return arr
            
    def swap(self, nums, i, j):
        t = nums[i]
        nums[i] = nums[j]
        nums[j] = t
        
    def permute_temp(self, nums, low, high, arr):
        i = low
        if low == high:
            arr.append(nums)
            return
        while i <= high:
            self.swap(nums, i, low)
            self.permute_temp(nums, low + 1, high, arr)
            self.swap(nums, i, low)
            i += 1
 

  思路沒問題,但是輸入題中測試資料卻得到 [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]],觀察下面程式碼

  def permute_temp(self, nums, low, high,arr):         i = low         if low == high:                arr.append(nums)                 return         while i <= high:             self.swap(nums, i, low)             self.permute_temp(nums, low + 1, high,arr)             self.swap(nums, i, low)             i += 1

  最終得到的列表肯定在紅色部分得到(遞迴出口),那麼我打印出每次的nums列表:

   if low == high:                  arr.append(nums)             print(nums)             return

得到結果[1, 2, 3],[1, 3, 2],[2, 1, 3],[2, 3, 1],[3, 2, 1],[3, 1, 2],這個結果又是正確的,嘗試列印nums列表的地址得到都是一樣的地址,而arr中儲存的是地址,雖然arr每次都append正確的資料,但是這是在遞迴函式中,每一層函式結束之後nums地址是要被pop掉的,這樣nums只能指向[1,2,3]

2.解決方法:每次將nums複製到一個新的列表中,使他們的地址都不一樣。

if low == high:             c=nums[:]             arr.append(c)             return

class Solution:
    """
    @param: nums: A list of integers.
    @return: A list of permutations.
    """
    def permute(self, nums):
        # write your code here
        arr = []
        if len(nums) == 0:
            return [[]]
        elif len(nums) == 1:
            return [nums]
        else:
            self.permute_temp(nums, 0, len(nums)-1, arr)
            return arr
            
    def swap(self, nums, i, j):
        t = nums[i]
        nums[i] = nums[j]
        nums[j] = t
        
    def permute_temp(self, nums, low, high, arr):
        i = low 
        if low == high:
            c = nums[:]
            arr.append(c)
            return
        while i <= high:
            self.swap(nums, i, low)
            self.permute_temp(nums, low + 1, high, arr)
            self.swap(nums, i, low)
            i += 1