判断一个链表是否为回文结构
一、题目
给定一个链表的头节点 head,请判断该链表是否为回文结构。
如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。
leetcode:https://leetcode.cn/problems/aMhZSa/
二、思路
我们可以使用栈的性质来做,将链表中的元素插入到栈中。栈有先进后出的性质,所以当把所有元素插入进去之后,从栈中依次取出来的元素顺序就是从链表的尾部向头部遍历的过程。在和原链表进行比对即可。这是第一种思路。
如上的这种思路还有可以优化的余地,我们不用插入链表中所有的元素,我们只需要插入链表中一半的元素即可。并且插入链表的后半部分。如果链表的长度是奇数,那就忽略最中间的那个元素;如果链表的长度是偶数,那就可以等分。可以使用快慢指针获取到链表的中间位置。
三、代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include <stack> #include <iostream>
struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} };
class Solution { public: bool isPalindrome(ListNode* head) { if (head == nullptr || head->next == nullptr) { return head; } ListNode* fast = head, *slow = head; for (; fast != nullptr && fast->next != nullptr;) { fast = fast->next->next; slow = slow->next; } if (fast != nullptr && fast->next == nullptr) { slow = slow->next; } while (slow != nullptr) { st_.emplace(slow->val); slow = slow->next; } while (!st_.empty() && head != nullptr) { if (st_.top() != head->val) { return false; } st_.pop(); head = head->next; } if (!st_.empty()) { return false; } return true; }
private: std::stack<int> st_; };
|
由于使用了栈,所以空间复杂度为 O(n),时间复杂度也为 O(n)