您的位置:首页 > 其它

LeetCode-Q46-Permutations

2017-09-14 16:13 337 查看
即为对给定的不含相同元素的数组进行全排列,并输出结果。

DFS解法:

def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def perm(res, s, nums, max):
if len(s) == max:
res.append(s)
for i in xrange(len(nums)):
temp = nums[:]
ts = temp[i]
temp.remove(temp[i])
perm(res, s+[ts], temp, max)

res = []
perm(res, [], nums, len(nums))
return res


参考Discuss的遍历解法:

原解法(Python解法中用时最短):基本思路为对原列表遍历,将下一个数插入已排好序列的每一个可能位置,如将3插入[1,2],有[3,1,2],[1,3,2],[1,2,3]所有情况。

def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
from copy import deepcopy
res = [ [] ]
for i in range( len( nums ) ):
tmp = []
for ele in res:
for j in range( i+1 ):
tmp.append(ele[:j]+[nums[i]]+ele[j:])

res = tmp

return res


另解:思路为循环遍历原列表,每次加入一个数,如最开始为[[]],第一次遍历原列表后得到[[1], [2], [3]],第二次遍历列表得到[[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]],直到每个子列表长度达到原列表长度。因为重复了很多比较,所以时间复杂度较原解法长不少。

def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = [[]]
while(len(res[0])<len(nums)):
temp = []
for ele in res:
for i in xrange(len(nums)):
if nums[i] in ele: continue
temp.append(ele+[nums[i]])
res = temp
return res


还在提交里看到直接调用python库itertools里的permutations函数提交的,用时很短,于是去看看了permutations()的源码:

def permutations(iterable, r=None):
# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
# permutations(range(3)) --> 012 021 102 120 201 210
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = range(n)
cycles = range(n, n-r, -1)
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return


有点繁杂没仔细看,因为看到了下面另一种官方实现方法,利用函数product(计算可迭代对象之间的笛卡尔积)实现:

去掉笛卡尔积中具有重复元素的那部分,其余的即为符合排列的结果

def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
for indices in product(range(n), repeat=r):
if len(set(indices)) == r:#去掉具有重复元素的子集,如(0,0)
yield tuple(pool[i] for i in indices)


其中product的实现为:

def product(*args, **kwds):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
pools = map(tuple, args) * kwds.get('repeat', 1)
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)


即为两个for loop的遍历。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dfs 排列