题目要求:
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
1->2->2->1
返回:true
解题思路:使用快慢指针找到链表的中间结点,然后将中间结点及之后的结点反转,得到形如
1->2->3<-2<-1
1->2->3->3<-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;
}else if(A->next == NULL){
return true;
}
ListNode *fast = A,*slow = A;
while(fast != NULL && fast->next != NULL){
fast = fast->next->next;
slow = slow->next;
}
ListNode *p = slow->next;
ListNode *p1 = p->next;
while(p != NULL){
p->next = slow;
slow = p;
p = p1;
p1 = p1->next;
}
//if(A->val == slow->val){
while(A != slow){
if(A->val != slow->val){
return false;
}
if(A->next = slow){
return true;
}
A = A->next;
slow = slow->next;
}
//}
return true;
}
};
如果需要不改变原先链表的结构,则可以先使用快慢指针找到中间结点以及尾结点,然后每次从中间结点开始向后找到当前尾指针的前一个结点,依次比较,直到头指针为中间结点为止。