🔥博客主页: 我要成为C++领域大神
🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】
❤️感谢大家点赞👍收藏⭐评论✍️
本博客致力于分享知识,欢迎大家共同学习和交流。
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
方法一:双端队列比较首尾
流程:
1、创建一个deque类型的容器,将链表节点元素值依次入队
2、比较队列首尾元素值是否相同
①相同,首尾出队,继续比较
②不相同,不是回文链表,返回false
3、若循环正常结束,队列为空,是回文链表,返回true
代码实现:
/**
* 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) {
deque<int> d;
while (head != nullptr) {
d.push_back(head->val);
head = head->next;
}
while (d.size() > 1) { // 只有剩余一个或零个元素时停止循环
if (d.front() != d.back()) {
return false;
}
d.pop_front();
d.pop_back();
}
return true;
}
};
方法二:折半拆分逐个比较
流程:
1、将链表从中间节点断开
2、对后一半的链表进行翻转
3、比较两个链表是否相同
代码实现:
/**
* 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 *mid=FindMid(head);
ListNode *L1=head;
ListNode *L2=mid->next;
L2=reverseList(L2);
return isSame(L1,L2);
}
private:
bool isSame(ListNode *headA,ListNode *headB){
ListNode *p1=headA;
ListNode *p2=headB;
while(p2!=nullptr){
if(p1->val!=p2->val)
return false;
p1=p1->next;
p2=p2->next;
}
return true;
}
ListNode* reverseList(ListNode* head) {
if(head==nullptr) return nullptr;
ListNode *p1=nullptr;
ListNode *p2=head;
ListNode *p3=head->next;
while(p3){
p2->next=p1;
p1=p2;
p2=p3;
p3=p3->next;
}
p2->next=p1;
return p2;
}
ListNode *FindMid(ListNode *head){
ListNode *pFast=head;
ListNode *pSlow=head;
while(pFast->next && pFast->next->next){
pFast=pFast->next->next;
pSlow=pSlow->next;
}
return pSlow;
}
};