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