Редакция для Можно ли переставить в палиндром
Submitting an official solution before solving the problem yourself is a bannable offence.
Разбор задачи «Можно ли переставить в палиндром»
1. Идея
Нужно понять, можно ли из букв строки, просто переставив их, получить палиндром.
Главное свойство палиндрома такое:
- буквы слева и справа должны идти парами;
- значит, почти все буквы должны встречаться чётное число раз;
- только одна буква может встретиться нечётное число раз — она будет стоять в центре, если длина строки нечётная.
Поэтому задача сводится к подсчёту количества букв, у которых нечётная частота.
- если таких букв не больше одной, ответ
YES; - иначе ответ
NO.
2. Наблюдения
Наблюдение 1
В палиндроме символы, кроме, возможно, центрального, всегда образуют пары.
Например:
abba—aиbвстречаются по 2 раза;abcba—aиbвстречаются по 2 раза,cвстречается 1 раз и стоит в центре.
Наблюдение 2
Если нечётных частот больше одной, собрать палиндром нельзя.
Пример: строка ab.
aвстречается 1 раз;bвстречается 1 раз.
Нечётных частот две, а центр в палиндроме только один. Значит, ответ NO.
Наблюдение 3
Так как строка состоит только из строчных латинских букв, достаточно массива из 26 элементов, где cnt[i] — количество вхождений буквы с номером i.
3. Алгоритм
- Считать строку
s. - Создать массив
cntиз 26 нулей. - Для каждого символа строки увеличить счётчик соответствующей буквы.
- Посчитать, сколько значений в
cntнечётные. - Если число нечётных частот
<= 1, вывестиYES, иначе вывестиNO.
4. Почему это работает
Докажем, что критерий odd <= 1 является правильным.
Если палиндром можно составить, то odd <= 1
В палиндроме символы на симметричных позициях одинаковы. Значит, все буквы, кроме, возможно, одной центральной, используются попарно. Тогда:
- если длина строки чётная, все частоты обязаны быть чётными;
- если длина строки нечётная, ровно одна буква может иметь нечётную частоту.
Следовательно, количество нечётных частот не может быть больше 1.
Если odd <= 1, то палиндром можно составить
Если нечётных частот нет, то все буквы можно разбить на пары и расставить симметрично слева и справа.
Если нечётная частота ровно одна, одну букву можно поставить в центр, а остальные буквы снова разбить на пары и расположить симметрично.
Значит, в обоих случаях палиндром существует.
Итак, условие odd <= 1 не только необходимо, но и достаточно.
5. Сложность
Подсчёт частот занимает O(n), где n — длина строки.
Проверка 26 букв занимает O(1).
Итоговая сложность:
- время:
O(n) - память:
O(1), так как используется массив фиксированного размера 26
6. Код на C++17
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
vector<int> cnt(26, 0);
for (char c : s) {
cnt[c - 'a']++;
}
int odd = 0;
for (int x : cnt) {
if (x % 2 != 0) {
odd++;
}
}
if (odd <= 1) {
cout << "YES\n";
} else {
cout << "NO\n";
}
return 0;
}
7. Код на Python 3
s = input().strip()
cnt = [0] * 26
for c in s:
cnt[ord(c) - ord('a')] += 1
odd = 0
for x in cnt:
if x % 2 != 0:
odd += 1
if odd <= 1:
print("YES")
else:
print("NO")
Комментарии