回文链表结构
偶数个节点
奇数个节点
判断方法
通过一个寻找链表中点的函数,如果为偶数个节点,则返回中间两个的前一个节点,如果为奇数个节点,则返回中间节点,再通过一个反转链表的函数,将中间节点后面的链表翻转,建立两个指针,一个给链表的头,一个给中间节点的下一个,同时从两个指针遍历,判断节点是否相同。
寻找中间节点函数
代码:
struct ListNode*middleNode(struct ListNode*head)
{
struct ListNode*slow,*fast;
slow = fast = head;//初始化快慢指针
while(fast && fast->next)
{
slow = slow->next;//slow一步
fast = fast->next->next;//fast两步
}
return slow;//返回中间节点
}
通过快慢指针的方式返回中间节点,slow走一步,fast走两步,当fast或fast->next 为空时,slow则为中间节点,返回slow.
链表翻转函数
代码:
struct ListNode*reverseList(struct ListNode*head)
{
struct ListNode*cur=head;//建立当前节点给原始链表的头
struct ListNode*newhead=NULL;//建立新的头节点为空
while(cur)
{
struct ListNode *next=cur->next;
//next指针为cur的下一个节点
cur->next=newhead;
//将当前指针的下一个节点指向新的头
newhead=cur;
cur=next;
//迭代往后走
}
return newhead;
}
定义三个指针,新的头节点指向空,一个当前节点为原来节点的头,和当前节点的下一个节点,遍历当前节点,将cur->next指向newhead,进行翻转,再迭代往后走,全部翻转后,newhead到了原来链表的最后的节点,返回newhead为新节点。
主函数
代码:
bool isPalindrome(struct ListNode* head)
{
struct ListNode*mid=middleNode(head);
//找中间节点
struct ListNode*rHead=reverseList(mid);
//翻转中间节点为头的链表
struct ListNode*curA=head;
struct ListNode*curR=rHead;
//遍历两个链表,判断节点是否相同,
while(curA&&curR)
{
if(curA->val!=curR->val)
{
return false;
}
else
{
curA=curA->next;
curR=curR->next;
}
}
return true;
}
相关题目
LeetCode: 回文链表