palindromeRearranging
Подскажите пожалуйста, я тут решал задачку на CodeSignal:"palindromeRearranging" и немного встрял. Суть такая: на вход приходит строка рандомная и нужно понять: будет ли строка палиндромом, если мы перетасуем элементы в ней.
Первая мысль, что пришла в голову: разделить строку на две части, дальше их отсортировать и проверять равные ли они, но потом понял, что идея не очень-то и работает.
И вот вспомнил про великий компонент collections.Counter, через который написал следующий код:
import collections
def palindromeRearranging(inputString):
rearrange = False
c = collections.Counter()
b = []
for i in inputString:
c[i] += 1 # считаю каждую букву
freq_list = c.values()
minimum = min(freq_list) # количество реже всего встречающихся букв
maximum = max(freq_list) # количество чаще всего встречающихся букв
if maximum % 2 == 0 or maximum == 1: # палиндром будет тогда, когда число самых встречающихся букв будет четное или если оно равно 1
for i in c:
if (c[i] == minimum): # если число определенных букв в строке повторяется минимальное количество раз, то заносим букву в массив b
b.append(i)
if len(b) > minimum or len(b) == 0: # если в массиве больше букв, чем минимальное число или если в массиве вообще нет букв, то возвращаем False
return rearrange
else: return True
В целом мне понравилась моя идея и хотел держаться ее, хоть это и два цикла (время страдает) плюс из-за массива b сложность по памяти возрастает. Но ночью ничего лучше не смог придумать.
Было бы круто, если бы кто-то помог понять, в чем проблема данного кода.
ЗАРАНЕЕ БЛАГОДАРЮ!
UPD: с кодом в одну строку мы почти спелись, тогда добавляется еще вопрос: как прийти к такому навыку однострочья и полезно ли это? особенно в читабельности
from collections import Counter
def palindromeRearranging(s):
print (Counter(s).values())
return sum(i % 2 == 1 for i in Counter(s).values()) <= 1
Ответы (1 шт):
Первый код непонятный и избыточный. Зачем вы вручную инкрементируете частоту элементов в Counter, когда он сам это должен делать? Ну и идея какая-то странная. Не важно, частые буквы или редкие, не должно быть никаких букв в строке, встречающихся нечётное число раз, кроме может быть одной максимум. Редкие буквы или частые - разницы никакой нет.
Второй код почти идеальный, только можно не проверять равенство, i % 2 == 1 и i % 2 дают одинаковое значение, поэтому можно суммировать просто i % 2.
И если тут речь о фразах-палиндромах, а не одиночных словах, например, если в терминах данной задачи фраза "А роза упала на лапу Азора" является палиндромом, то нужно ещё:
- убирать/не считать пробелы - в фразах-палиндромах они могут расставляться произвольно, имеющееся число пробелов соблюдать не нужно
- приводить все буквы к одному регистру - потому что опять же регистр можно менять при перетасовывании букв