Учитывая список элементов в лексикографическом порядке (то есть ['a', 'b', 'c', 'd']), найдите n-ю перестановку - Среднее время для решения? - PullRequest
3 голосов
/ 22 июля 2011

Я наткнулся на этот вопрос интервью:

Учитывая список элементов в лексикографическом порядке (то есть ['a', 'b', 'c', 'd']), найдите n-ю перестановку

Я попробовал сам, и мне потребовалось ~ 30 минут, чтобы решить. (Я закончил с решением ~ 8-9 в Python). Просто любопытно - сколько времени "нужно" займет, чтобы решить этот тип проблемы? Я принимаю слишком долго?

Ответы [ 3 ]

10 голосов
/ 22 июля 2011

9 мин, включая тест

import math

def nthperm(li, n):
    n -= 1
    s = len(li)
    res = []
    if math.factorial(s) <= n:
        return None
    for x in range(s-1,-1,-1):
        f = math.factorial(x)
        d = n / f
        n -= d * f
        res.append(li[d])
        del(li[d])
    return res

#now that's fast...
nthperm(range(40), 123456789012345678901234567890)
0 голосов
/ 09 сентября 2017

На всякий случай, если кто-то заинтересован в решении, которое может найти «i-ю» перестановку, когда вы смотрите на «r-length-permutations» (как представлено аргументом r в itertools.permutations):

from math import factorial

def ith_permutation(i, seq, r=None):
    li = list(seq)
    length = len(li)

    if r is None:
        r = length
    res = []
    current_factorial = factorial(length) // factorial(length - r)

    if current_factorial <= i:
        raise ValueError('out of range')

    for x in range(length, length-r, -1):
        current_factorial //= x
        div, mod = divmod(i, current_factorial)
        i = mod
        res.append(li[div])
        del(li[div])

    return res

Например:

>>> ith_permutationutation(10, [0, 1, 2, 3, 4], 2)
[2, 3]

>>> # correctness check:
>>> from itertools import permutations
>>> list(permutations([0, 1, 2, 3, 4], 2))[10]
(2, 3)

Включая более полный тест:

s = range(8)
for n in range(len(s)):
    for idx, item in enumerate(permutations(s, n)):
        assert list(item) == ith_permutation(idx, s, n)

Здесь использовались некоторые части ответа Кароли Хорват..

0 голосов
/ 26 июля 2011

Возможно, я что-то упустил, я думал, что мы можем легко найти это с помощью nth из рецептов itertools и перестановок :

from itertools import permutations, islice
def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(islice(iterable, n, None), default)
def main():
    data = ['a', 'b', 'c', 'd']
    n = 7  # 0 indexed
    print nth(permutations(data), n)
if __name__ == "__main__":
    main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...