我有一个这样的列表:
from itertools import permutations
l = [1,1,1,1,1,1,1,2]
原始列表中的重复“1”条目意味着不同的排列仅取决于输出中出现“2”的位置;所以只有8种不同的排列。但是permutations()函数将生成所有阶乘(8)= 40320排列。我知道我可以在事后使用set()函数删除重复的输出,但算法仍然是O(N!),我想要更高效的东西。
这里有几个有效的解决方案,不使用set
,基本上是关于避免插入重复元素。
# To handle duplication, just avoid inserting a number before any of its duplicates.
def permuteUnique1(nums):
ans = [[]]
for n in nums:
new_ans = []
for l in ans:
for i in range(len(l) + 1):
new_ans.append(l[:i] + [n] + l[i:])
if i < len(l) and l[i] == n: break # handles duplication
ans = new_ans
return ans
# Duplication happens when we insert the duplicated element before and after the same element,
# to eliminate duplicates, just insert only after the same element.
def permuteUnique2(nums):
if not nums:
return []
nums.sort()
ans = [[]]
for n in nums:
new_ans = []
l = len(ans[-1])
for seq in ans:
for i in range(l, -1, -1):
if i < l and seq[i] == n:
break
new_ans.append(seq[:i] + [n] + seq[i:])
ans = new_ans
return ans
# Build the list of permutations one number at a time, insert the number into each already built permutation
# but only before other instances of the same number, never after.
def permuteUnique3(nums):
perms = [[]]
for n in nums:
perms = [p[:i] + [n] + p[i:]
for p in perms
for i in range((p + [n]).index(n) + 1)]
return perms
# or as "one-liner" using reduce:
from functools import reduce
def permuteUnique4(nums):
return reduce(lambda perms, n: [p[:i] + [n] + p[i:]
for p in perms
for i in range((p + [n]).index(n) + 1)],
nums, [[]])
你可以在qazxsw poi找到更多解决方案和解释。希望对您有所帮助,并在您有其他问题时发表评论。 :)