题目描述:
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
解题思路1:
通过使用 itertools.permutations()
功能函数,来返回可迭代对象的所有数学全排列方式。
代码1:
import itertools
import numpy as np
class Solution:
def permute(self, nums):
return np.array(list(itertools.permutations(nums)))
nums = [1, 2, 3]
s = Solution()
print(s.permute(nums))
结果为:
[[1 2 3]
[1 3 2]
[2 1 3]
[2 3 1]
[3 1 2]
[3 2 1]]
显然,这样的结果与输出不一样,因此,我们需要调整。将最后一行的返回变为:
return list(itertools.permutations(nums))
输出为:
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
程序在leetcode上通过了!
将最后一行变为:
return [list(i) for i in itertools.permutations(nums)]
输出为:
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
解题思路2:
- 找出每一个数字,放在最前面;
- 递归的将剩余的数组进行全排列,并和这个数字相加,生成新的数组
- 返回列表
代码2:
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if not nums:
return []
# 注意这里是返回[nums], 因为最后返回要求是一个List[List]。
if len(nums) == 1:
return [nums]
res = []
for i, v in enumerate(nums):
rest = nums[0:i] + nums[i+1:]
for comb in self.permute(rest):
res.append([v]+comb)
return res
结果为:
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
解题思路3:
- 采用广度优先搜索的思路,先假设全排列里只用了一个元素,然后再迭代的加入其他的元素,每次加入元素时分别对之前的全排列的结果在所有位置均可插入当前元素;
- 需要注意的是需要考虑添加元素时不能改变原来的结果,因此使用深拷贝来进行备份。
代码3:
import copy
class Solution(object):
def permute(self, nums):
if not nums:
return []
# 注意这里是返回[nums], 因为最后返回要求是一个List[List]。
ret = [[nums[0]]]
for i in range(1, len(nums)):
iteam = nums[i]
ret_copy = copy.deepcopy(ret) # 深copy上一轮的返回值,避免对原始值产生修改
curr = []
for ls in ret_copy:
for j in range(len(ls)+1):
ls_copy = copy.deepcopy(ls)
ls_copy.insert(j, iteam)
curr.append(ls_copy)
ret, curr = curr, ret
return ret
s = Solution()
nums = [1, 2, 4]
print(s.permute(nums))
class Solution:
def permute(self, nums):
if len(nums) <= 1:
return [nums]
res = [[nums[0]]]
index = 1
while index < len(nums):
tmp = []
for each in res:
for i in range(index+1):
tmp.append(each[:i]+[nums[index]]+each[i:])
res = tmp
index += 1
return res
class Solution:
def permute(self, nums):
if len(nums) <= 1:
return [nums]
res = []
perms = self.permute(nums[1:])
for each in perms:
for i in range(len(each)+1):
p = each[:i]+[nums[0]]+each[i:]
res.append(p)
return res
参考链接:
[1]. 递归 Leetcode 46 全排列
来源:https://leetcode-cn.com/problems/permutations
关于函数 itertools.permutations() 的拓展:
栗子:
两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比。请编程序找出三队赛手的名单。
import itertools
for i in itertools.permutations('xyz'):
if i[0] != 'x' and i[2] != 'x' and i[2] != 'z':
print('a vs %s, b vs %s, c vs %s' % (i[0], i[1], i[2]))
结果为:a vs z, b vs x, c vs y