lintcode 15 · 全排列
描述
给定一个数字列表,返回其所有可能的排列。
样例 2:
输入:
列表 = [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路一:回溯法。使用递归。
- 由于这是个排列问题,有先后顺序,我们需要将第一个位置分别设置为list中的数字。所以我们需要循环。
**2. 针对每一个循环,比如首位为1时,可看作[1]+[2,3]的全排列。也就list当前元素+剩余元素的全排列。**注意还包含这个元素前面的元素 - 我们将结果保存在临时列表tmp中,当tmp长度 == list长度时将tmp加入result中。我们在使用回溯法时总要注意产生结果的时机。
def permute(self, nums):
'''
def permutations(result,tmp,nums):
if not nums:
print "出结果了 tmp = ",tmp
result.append(tmp)
else:
#排列,每个位置都有可能是第一位。
for i in range(len(nums)):
print "tmp = ",tmp,"nums[i:i+1] =",nums[i:i+1],"nums = ",nums,"i = ",i
print "tmp + nums[i:i+1] = ",tmp + nums[i:i+1]
#tmp为临时列表,不断增长,nums[:i]+nums[i+1:]也就是nums为不包含nums[i]位置的剩余元素列表。
permutations(result,tmp+nums[i:i+1],nums[:i]+nums[i+1:])
#注意list为None和[]的区别。
result = []
if nums == None:
return []
elif nums == []:
return [[]]
else:
permutations(result,[],nums)
return result
非递归解法:
- 将nums中子元素作为子列表加入stack,作为结果的头。
2a. 对于stack中每个元素,将nums中的不在stack[-1]中的元素和stack[-1]结合,再压入stack中。
2b. 如果stack[-1]长度达到nums的长度,将其加入结果中。
def permute(self, nums):
if not nums:
return [[]]
result = []
stack = [[i] for i in nums]
while stack:
last = stack.pop()
print "last = ",last
if len(last) == len(nums):
result.append(last)
print "出结果了,result = ",result
continue
for n in nums:
if n not in last:
stack.append(last + [n])
print "after append ,stack = ",stack
return result