题目:回文链表. - 力扣(LeetCode)
题解:使用stl存储判定
使用stack栈的特性,先入后出,达到反转中心链表值得目的。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode* p = head;
stack<int>s;
int m = 0, t = 0;
while(p != NULL)
{
p = p->next;
m ++;
}
if(m == 1) return true;
p = head;
while(p != NULL)
{
t ++;
if(t <= m / 2) s.push(p->val);
else if(t >= m / 2 + 1 && m % 2 == 0 || t > m / 2 + 1 && m % 2 == 1)
{
if(s.top() == p->val) s.pop();
else return false;
}
p = p->next;
}
return true;
}
};
思考:如何达到空间复杂度O(1)?以及如何写单向链表的反转?
我们可以通过翻转链表,判断值来进行操作,通过修改指针达到效果。
public:
bool isPalindrome(ListNode* head) {
if (head == nullptr) {
return true;
}
// 找到前半部分链表的尾节点并反转后半部分链表
ListNode* firstHalfEnd = endOfFirstHalf(head);
ListNode* secondHalfStart = reverseList(firstHalfEnd->next);
// 判断是否回文
ListNode* p1 = head;
ListNode* p2 = secondHalfStart;
bool result = true;
while (result && p2 != nullptr) {
if (p1->val != p2->val) {
result = false;
}
p1 = p1->next;
p2 = p2->next;
}
// 还原链表并返回结果
firstHalfEnd->next = reverseList(secondHalfStart);
return result;
}
这里主要涉及了两个过程,一个是快慢指针,一个是翻转链表。
快慢指针的作用是读取一半的链表,翻转链表顾名思义。
快慢指针的做法:
快指针一次走两步,慢指针一次走一步,快指针走完时,慢指针刚好走了一半。
代码如下:
ListNode* endOfFirstHalf(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
翻转链表过程如下,红色为举例:
1. 创建两个新链表,当前节点链表(curr)与前驱节点(prev)
2. 遍历链表
1->2->3->4
2-1 定义新节点,指向当前节点的下一个节点
nextTemp = curr->next = 2 1->2->3->4
2-2 将当前的节点的指针指向上一个节点
curr->next = prev = nullptr, 1<-2->3->4
2-3 将当前节点当成前驱节点
prev = curr = 1
2-4 将当前节点更新为下个节点
curr = nextTemp
代码如下:
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;//记录前驱
ListNode* curr = head;//头
while (curr != nullptr) {
ListNode* nextTemp = curr->next;//定义新的指针指向当前的下一个
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
完整代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head == nullptr) return true;
ListNode* first = fastandslow(head);
ListNode* second = reverse(first->next);
bool ans = true;
ListNode* p1 = head, *p2 = second;
while(ans && p2 != nullptr)
{
if(p1->val != p2->val) ans = false;
p1 = p1->next;
p2 = p2->next;
}
first->next = reverse(second);
return ans;
}
ListNode* reverse(ListNode* head)
{
ListNode* prev = nullptr;
ListNode* curr = head;
while(curr != nullptr)
{
ListNode* nextemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextemp;
}
return prev;
}
ListNode* fastandslow(ListNode *head)
{
ListNode* fast = head;
ListNode* slow = head;
while(fast->next != nullptr && fast->next->next != nullptr)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};