题目描述
链表的回文结构
对于一个链表,请设计一个**时间复杂度为O(n),额外空间复杂度为O(1)**的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900
输入:1->2->3->2->1
输出:true
题解
先用快慢指针得到该链表的中间结点和尾结点,然后再将中间结点所指向的位置往后进行逆置,得到的逆置后的链表和原链表的val一 一做比较,如果都相等,则为回文结构。
初始情况:
mid 为慢指针,最终会走到中间结点,tail为快指针,最终会走到尾结点
①mid 一次走一个,tail一次走两个,直到 tail == NULL或 tail -> next == NULL为止。
②将mid 所指的位置向后进行逆置,如果tail == NULL,则说明该链表的长度为偶数个,在逆置时直接逆置mid所指位置即可,若tail->next == NULL,则说明链表的长度为奇数个,则在逆置时需要逆置mid->next位置的链表
tmp为逆置后链表的指针,head为原链表的头指针
③将head 和 tmp的val做比较,如果相等就向下走,不相等就返回false,直到 tmp == NULL(链表为奇数个) 或者 head == tmp时结束(链表为偶数个)
题解代码
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
if(A == NULL || A->next == NULL )
{
return false;
}
//先用快慢指针得到中间结点和最后一个结点
struct ListNode* head = A;
struct ListNode* mid = A;
struct ListNode* tail = A;
//struct ListNode* midMove = NULL;
//获得头尾指针
while(tail)
{
mid = mid->next;
if(tail->next == NULL){
//表明链表个数为奇数个
//则中间移动指针要向后走一个
//midMove = mid;
mid = mid->next;
break;
}
else if(tail->next->next == NULL)
{ //表明链表个数为偶数个
mid = mid->next;
tail = tail->next;
//midMove = mid;
break;
}
else{
tail = tail->next->next;
}
}
//将mid指向的链表逆置
struct ListNode* tmp = reverseList(mid);
while(tmp && head->next != tmp)
{
if(tmp->val != head->val)
{
return false;
}
else{
tmp = tmp->next;
head = head->next;
}
}
return true;
}
//逆置链表
struct ListNode* reverseList(ListNode* A)
{
if(A == NULL || A->next == NULL)
{
return A;
}
struct ListNode* head,* tail,* tmp;
head = A;
tail = A->next;
head->next = NULL;
while(tail)
{
tmp = tail->next;
tail->next = head;
head = tail;
tail = tmp;
}
return head;
}
};