形如
1->2->3->2->1
1->2->3->3->2->1
之类的称为回文链表,分奇数个数和偶数个数
判断是否为回文链表解法:
第一步:求得中间节点(不管总个数奇数还是偶数,都需要)。恰好,链表的中间节点可用快慢指针求得:slow走一步,fast走两步,fast或fast->next为NULL时,奇数个,返回链表的中间结点;如果有两个中间结点(偶数个),则返回第二个中间结点。参考力扣
实现如下
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* fast=head;
struct ListNode* slow=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
第二步:翻转中间节点后的链表。参考:力扣 解法:不停拿出第一个节点,头插,直至为NULL
代码实现如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
if(head==NULL)
{
return head;
}
else
{
struct ListNode* prev=NULL;
struct ListNode* cur=head;
struct ListNode* next=head->next;
while(next!=NULL)
{
cur->next=prev;
prev=cur;
cur=next;
next=next->next;
}
cur->next=prev;
return cur;
}
}
第三步:对比头链表和翻转后的链表,相同比对下一个,不同返回flase。
注意不用改变中间节点的前一个节点的指向,因为只要有一个为NULL,就停止对比了
代码实现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* fast=head;
struct ListNode* slow=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
struct ListNode* reverseList(struct ListNode* head){
if(head==NULL)
{
return head;
}
else
{
struct ListNode* prev=NULL;
struct ListNode* cur=head;
struct ListNode* next=head->next;
while(next!=NULL)
{
cur->next=prev;
prev=cur;
cur=next;
next=next->next;
}
cur->next=prev;
return cur;
}
}
bool isPalindrome(struct ListNode* head){
struct ListNode* midNode=middleNode(head);//求中间结点
struct ListNode* revList=reverseList(midNode);//逆置中间结点后的链表
while(head&&revList)
{
if(head->val!=revList->val)
{
return false;
}
else{
head=head->next;
revList=revList->next;
}
}
return true;
}