Проработав мой путь через "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)
Во-первых, авторское решение представляет собой оптимизированную версию 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)
, вероятно, превзойдет решение автора, если алгоритмически решение автора лучше.
Для первого кода это может быть легко с помощью 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)
.
Поэтому, в общем, первый алгоритм имеет наилучшую временную сложность и легко реализуется.
return Counter(str1) == Counter(str2)
?perm("ABB", "BAA")
, которые не являются перестановками друг друга. Авторское решение подсчитывает вхождения символов.