Глубокое погружение в проблему связанного списка палиндромов на LeetCode.
Введение
Задача «Связанный список палиндромов» — это классическая задача по программированию, которая проверяет вашу способность манипулировать связанными списками и проверять наличие палиндромов. В этой статье мы обсудим различные решения этой проблемы, но наше внимание будет сосредоточено на использовании рекурсивного подхода для ее решения.
Обзор проблемы
Задача представляет нам односвязный список и просит определить, является ли этот список палиндромом или нет. Палиндром — это последовательность символов, которая читается как вперед, так и назад. (здесь» ссылка на проблему)
Что такое Палиндром?
Палиндром — это слово, предложение, стих или даже число, которое одинаково читается как вперед, так и назад. Например: гоночный автомобиль; то же самое, если мы читаем это слева или справа.
В Палиндроме много проблем, мы можем применить их к строке или числу. Однако наша сегодняшняя задача применима к односвязному списку, что немного сложнее 😁
Решения
Решений этой проблемы много, вот некоторые из них:
- Преобразование в массив:
Перейдите по связанному списку и сохраните значения в массиве, затем используйте два указателя: один в начале, другой в конце (это возможно благодаря индексам). Хороший способ обойти проблему, но это не так и будет большая сложность пространства из-за дополнительной структуры данных (буфера). но это работает 🙋 - Использование стека:
Пройдите по связанному списку и поместите все элементы в стек, затем снова пройдите по связанному списку, извлекая элементы из стека.
Наконец, сравните извлеченные элементы с элементами связанного список. (Хорошо, но то же самое, что и выше в отношении пространственной сложности)
И много-много решений, таких как: перевернуть вторую половину и т. д.
Есть ли оптимизированный способ решения этой проблемы? без буфера? Что ж, я рад сказать ДА!
Интуиция 🧠
Есть ли способ одновременно перемещаться по связанному списку вперед и назад?
Когда я задал себе этот вопрос, мне сразу на ум пришел Возврат. Нормально, но, как?
Используя рекурсию, вы можете перемещаться по связанному списку в прямом направлении, что очень просто. Однако есть ли способ сделать это наоборот? Ответ – ДА!
Сложная часть заключается в том, где вызывать рекурсивную функцию: вы будете вызывать ее до логики функции или после? Если вы вызывали его раньше, последний узел будет первым, который завершит логику функции. а если после этого, это нормальная ситуация, первым будет обработан первый узел.
При таком подходе теперь у вас есть два указателя, работающих одновременно, что позволяет сравнивать значения. И это все, что нужно!
Код
/** * Definition for singly-linked list. * function ListNode(val, next) { * this.val = (val===undefined ? 0 : val) * this.next = (next===undefined ? null : next) * } */ /** * @param {ListNode} head * @return {boolean} */ var isPalindrome = function(head) { let result = true; const backtrack = (head2) => { if(!head2 || !head) return; backtrack(head2.next); if(head2.val !== head.val) result = false; head = head.next; } backtrack(head); return result; };
Примечание. head
и head2
— это два указателя, о которых мы говорили, где head2
— правый, а head
— левый.
Кстати, решение идеально соответствует последующей заметке о LeetCode.
Заключение
В этой статье мы рассмотрели рекурсивный подход к решению проблемы связанного списка палиндромов в LeetCode. Используя умную технику рекурсивного сравнения, мы можем эффективно определить, является ли данный связанный список палиндромом или нет.
Это моя первая статья, и я рад услышать ваши отзывы!
Спасибо и всем удачного кодирования!! 💙