перестановки с повторением в python (чтобы не использовать метод set () илиiform ()) - PullRequest
1 голос
/ 04 апреля 2019

У меня есть такой список:

from itertools import permutations
l = [1,1,1,1,1,1,1,2]

Повторяющиеся записи «1» в исходном списке означают, что различные перестановки зависят только от того, где «2» появляется в выходных данных; таким образом, есть только 8 различных перестановок. Но функция permutations () будет генерировать все факториальные (8) = 40320 перестановок. Я знаю, что могу удалить повторяющиеся выходные данные, используя функцию set () после факта, но алгоритм все еще O (N!), И я хотел бы что-то более эффективное.

1 Ответ

0 голосов
/ 04 апреля 2019

Вот несколько эффективных решений, которые не используют 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, [[]])

Вы можете найти больше решений и объяснений в LeetCode . Надеюсь, что это поможет вам, и прокомментируйте, если у вас есть дополнительные вопросы. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...