Что такое большое обозначение этих алгоритмов перестановки

1

Проработав мой путь через "Cracking the coding interview", и в практическом вопросе говорится

Учитывая 2 строки, напишите метод, чтобы решить, является ли это перестановкой другой.

Решение python автора выглядит следующим образом:

def check_permutation(str1, str2):
    if len(str1) != len(str2):
        return False
    counter = Counter()
    for c in str1:
        counter[c] += 1
    for c in str2:
        if counter[c] == 0:
            return False
        counter[c] -= 1
    return True 

Который утверждает, что находится в O (N) времени.

Мое решение таково:

def perm(str1,str2):
    if(len(str1) != len(str2)):
        return False
    for c in str1:
        if c not in Str2:
            return False
    return True 

И я считаю, что это тоже O (N). Это правда? Какой алгоритм благоприятен? Тип данных автора кажется ненужным.

И, наконец, является ли этот алгоритм O (NlogN)?

def perm(str1,str2):
    return sorted(str1)==sorted(str2)
  • 1
    Разве авторский код не может быть упрощен так: return Counter(str1) == Counter(str2) ?
  • 4
    Ваша функция возвращает true для perm("ABB", "BAA") , которые не являются перестановками друг друга. Авторское решение подсчитывает вхождения символов.
Показать ещё 5 комментариев
Теги:
python-3.x
algorithm
big-o
runtime

2 ответа

3
Лучший ответ

Во-первых, авторское решение представляет собой оптимизированную версию Counter(str1) == Counter(str2) (она возвращает False быстрее и создает один экземпляр Counter). Это, действительно, O(n) поскольку доступ к хэш-таблице (Counter) - O(1).

Далее, ваше решение является квадратичным (O(n^2)), потому что каждый in это O(n) - он должен пройти через всю строку. Это также неверно для строк с повторениями.

В-третьих, sorted(str1) == sorted(str2), действительно, является линейной (O(n*log(n))) и, следовательно, хуже исходного линейного решения.

Обратите внимание, однако, что для небольших строк константы могут иметь значение, и линейно-линейное (sorted) решение может оказаться быстрее линейного (Counter).

Наконец, будьте осторожны, что Python обычно реализуется с использованием интерпретатора, поэтому фактическая производительность может зависеть от того, используете ли вы функции, реализованные на C или в Python. Например, если Counter реализован на C, то Counter(str1) == Counter(str2), вероятно, превзойдет решение автора, если алгоритмически решение автора лучше.

0

Для первого кода это может быть легко с помощью collection.Counter вместо циклов:

def check_permutation(str1, str2):
    if len(str1) != len(str2):
        return False
    return Counter(str1) == Counter(str2)

И это O(n) снова. Последний алгоритм, так как сортировка и использование sorted это O(nlogn).

Ваш алгоритм неверен, поскольку вы находите символ внутри другой строки без учета количества повторений этого символа. Если бы это было так, это было бы O(n^2).

Поэтому, в общем, первый алгоритм имеет наилучшую временную сложность и легко реализуется.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню