
1 -> 2 -> 3 -> 2 -> 1
1 -> 2 -> 2 -> 1
上面两个是回文结构
图解

/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
//空链表==>不是回文结构
if(A == NULL)
{
return false;
}
//存放到数组中
int arr[900];//题目说了,链表长度小于等于900
int sz = 0;//标志数组元素
//遍历链表,存放元素到数组中
struct ListNode* curA = A;
while(curA)
{
//放到sz位置上,然后sz++
arr[sz++] = curA->val;
//curA指向下一个结点
curA = curA->next;
}
//对数组元素进行判断是否是回文结构
int left = 0;
int right = sz - 1;//最后一个元素
while(left < right)
{
if(arr[left] != arr[right])
{
return false;
}
left ++;
right --;
}
//数组元素比较完成,说明数组是回文结构 -> 链表是回文的
return true;
}
};
图解:
偶数个结点

奇数个结点

非回文

注意:反转之前的mid的前一个结点的next仍指向原来的位置

/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
//找链表的中间结点 - 快慢指针
struct ListNode* MidNode(struct ListNode* head)
{
if(head == NULL)
{
return NULL;
}
struct ListNode* slow = head;
struct ListNode* fast = head;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
//反转链表
struct ListNode* ReverseList(struct ListNode* head)
{
//只有一个结点/链表为空不用反转
if(head == NULL || head->next == NULL)
{
return head;
}
struct ListNode*n1= NULL,*n2 = head,*n3 = head->next;
while(n2)
{
// 反转
n2 ->next = n1;
//迭代往后走
n1 = n2;
n2 = n3;
//防止n3为空时还往后走,对空指针解引用
if(n3 != NULL)
{
n3 = n3->next;
}
}
return n1;
}
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
if(A == NULL)
{
return false;
}
//找中间结点
struct ListNode* mid = MidNode(A);
//反转中间结点后面的内容
struct ListNode* rhead = ReverseList(mid);
//遍历前后两部分链表
struct ListNode* curA = A;
struct ListNode* curR = rhead;
while(curA && curR)
//while(curR)可以
//while(curA)不可以
{
if(curA->val != curR->val)
{
return false;
}
curA = curA->next;
curR = curR->next;
}
return true;
}
};
为什么判断条件while(curR)可以,while(curA)不可以?
以上面图解的例子
若以curA为循环结束条件,即当curA指向NULL时才跳出循环,像上面这种情况,curR已经指向空了,再进入循环,就是对空指针进行访问了,出错
若以curR为循环结束条件是可以的
若是回文结构:奇数个结点时:curA和curR同时指向NULL结束 偶数个结点时:curR比curA先指向NULL结束
若不是回文,二者都不会走到NULL,比较时就返回false了
所以循环条件可以写成:while(curA&& curR) ->含义时:curA和curR都不为空就继续,其中一个为空就跳出循环
也可以写成while(curR)
但是不可以写成while(curA)