思路1:找到中间节点,从中间节点向后反转链表
寻找链表的中间节点和反转链表的程序已经讲解过
寻找链表的中间节点:CSDN
反转链表:CSDN
然后从头节点和中间节点依次向后比较节点的值
Note:
后半段链表反转后,需要更新mid的值
需要分奇数个节点的链表和偶数个节点的链表比较
1️⃣奇数个节点的链表
Note:
对于奇数个节点的链表,比较结束的条件是mid->next == NULL
2️⃣偶数个节点的链表
对于偶数个节点的链表,比较结束的条件是mid == NULL
参考代码如下:
bool chkPalindrome(ListNode* A) {
// write code here
//寻找中间节点
struct ListNode* slow = A;
struct ListNode* fast = A;
struct ListNode* head = A;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
struct ListNode* mid = slow;
//反转后半段
//struct ListNode* midhead = mid;
struct ListNode* n1 = NULL;
struct ListNode* n2 = mid;
struct ListNode* n3 = NULL;
while (n2)
{
n3 = n2->next;
n2->next = n1;
n1 = n2;
n2 = n3;
}
//反转之后,n2指向空,n1指向新的头
mid = n1;
//比较
while (mid && mid->next)
{
if (head->val == mid->val)
{
head = head->next;
mid = mid->next;
}
else
{
return false;
}
}
return true;
}
思路二:反转整个链表,从头结点开始与原链表依次比较
由上图:回文结构的链表反转后与原链表相同,非回文结构的链表反转后与原链表不同
参考代码如下:
bool chkPalindrome(ListNode* A)
{
//反转整个链表再比较
struct ListNode* newhead = NULL;
struct ListNode* n1 = NULL;
struct ListNode* n2 = A;
struct ListNode* n3 = NULL;
while (n2)
{
n3 = n2->next;
n2->next = n1;
n1 = n2;
n2 = n3;
}
newhead = n1;
//比较
struct ListNode* head = A;
while (head)
{
if (head->val == newhead->val)
{
head = head->next;
newhead = newhead->next;
}
else
{
return false;
}
}
return true;
}