Редакция для Проверка палиндрома
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Автор:
1. Идея
Нужно проверить, читается ли слово одинаково слева направо и справа налево.
Самый естественный способ — сравнивать символы с двух концов строки:
- первый с последним,
- второй с предпоследним,
- и так далее.
Если на каком-то шаге символы не совпали, слово точно не палиндром.
Если дошли до середины и все пары совпали, значит это палиндром.
2. Наблюдения
- У палиндрома симметричные символы должны быть равны.
- Проверять всю строку полностью не нужно: достаточно посмотреть только на пары до середины.
- Для этого удобно завести два указателя:
l— на левый конец,r— на правый конец.
- После каждой успешной проверки двигаем их навстречу:
l += 1r -= 1
Например, для строки level:
l = 0,r = 4→l == ll = 1,r = 3→e == e- указатели встретились, значит ответ
YES
Например, для строки abca:
a == ab != c→ сразуNO
3. Алгоритм
- Считать строку
s. - Установить:
l = 0r = len(s) - 1
- Пока
l < r:- если
s[l] != s[r], вывестиNOи завершить проверку; - иначе увеличить
lна 1 и уменьшитьrна 1.
- если
- Если цикл завершился без несовпадений, вывести
YES.
4. Почему это работает
По определению палиндрома строка должна совпадать со своей обратной записью.
Это означает, что для каждого индекса слева символ должен быть равен соответствующему символу справа.
То есть должны выполняться равенства:
s[0] == s[n - 1]s[1] == s[n - 2]s[2] == s[n - 3]- и так далее
Именно это и делает алгоритм с двумя указателями.
- Если хотя бы одна такая пара не совпадает, строка не может быть палиндромом.
- Если все пары совпали до середины, то условие палиндрома выполнено для всей строки.
Значит, алгоритм всегда выводит правильный ответ.
5. Сложность
Пусть длина строки равна n.
- По времени:
O(n), потому что каждый символ участвует в проверке не более одного раза. - По памяти:
O(1), так как используются только несколько переменных.
6. Код на C++17
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int l = 0;
int r = (int)s.size() - 1;
bool ok = true;
while (l < r) {
if (s[l] != s[r]) {
ok = false;
break;
}
l++;
r--;
}
if (ok) {
cout << "YES\n";
} else {
cout << "NO\n";
}
return 0;
}
7. Код на Python 3
s = input()
l = 0
r = len(s) - 1
ok = True
while l < r:
if s[l] != s[r]:
ok = False
break
l += 1
r -= 1
if ok:
print("YES")
else:
print("NO")
Комментарии