Под "связанным списком" вы подразумеваете std::list
?
template <typename BiDiIterator>
bool isPalindrome(BiDiIterator first, BiDiIterator last) {
if (first == last) return true;
--last;
if (first == last) return true;
if (*first != *last) return false;
return isPalindrome(++first, last); // tail recursion FTW
}
isPalindrome(mylist.begin(), mylist.end());
Я использовал тот факт, что можно итерировать как с конца, так и с начала. Неясно, задано ли это вопросом.
Используя односвязный список, вы можете запустить два итератора, один быстрый и один медленный. При каждом вызове увеличивайте один быстрый и медленный один раз. Когда быстрый достигает конца списка, медленный находится в средней точке (ит, +/- 1 с учетом списков нечетной и четной длины). В этот момент вернитесь из своей рекурсии, сравнивая значения символов. & Theta; (n) сложность для времени выполнения и использования памяти (не хвостовая рекурсия).
Я бы написал код, но пришло время спать здесь, в Великобритании.
[Редактировать: все утро
template <typename FwdIterator>
std::pair<FwdIterator, bool> isPalindrome(FwdIterator slow, FwdIterator fast, FwdIterator last) {
if (fast == last) return std::make_pair(slow, true);
++fast;
if (fast == last) return std::make_pair(++slow, true);
++fast;
FwdIterator next = slow;
std::pair<FwdIterator, bool> result = isPalindrome(++next, fast, last);
if (result.second == false) return result;
if (*slow != *(result.first)) return std::make_pair(slow, false);
++(result.first);
return result;
}
...
isPalindrome(mylist.begin(), mylist.begin(), mylist.end()).second;
Если по какой-то странной причине в вашем связанном списке нет итератора, то, надеюсь, эквивалентный код с if (fast->next == 0)
, fast = fast->next
и т. Д. Очевиден. И, конечно, вы можете привести в порядок пользовательский интерфейс с помощью оболочки.
Я думаю, что вы можете избежать дополнительного хранилища, если вам разрешено временно изменять список, переворачивая список до «медленного» при спуске, а затем снова переворачивая его при подъеме. Таким образом, вам не нужно хранить копию slow
в рекурсивном вызове: вместо этого вы можете вернуть дополнительный указатель для вызывающего абонента. Я не собираюсь беспокоиться.
] * * тысячу двадцать-один