题目:
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断该链表是否回文。
边界条件:
传入指针为空。
思路:
先通过两个指针,来找到中间结点指针mid,然后mid指针到链表末端开始回溯,另一个指针head开始和这个指针的值进行比较。
#include <iostream>
using namespace std;
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode *GetMidNode(ListNode *head){
if (head == NULL) return NULL;
int size = 1;
ListNode *faster = head;
ListNode *slower = head;
while (faster->next)
{
if (faster->next->next)
{
faster = faster->next->next;
size += 2;
}
else
{
faster = faster->next;
size += 1;
}
slower = slower->next;
}
if (size != 1 && size % 2 == 1) slower = slower->next;
return slower;
}
bool RecurCheck(ListNode *&head, ListNode *mid)
{
if (mid == NULL) return true;
if (!RecurCheck(head, mid->next))
return false;
if (head->val == mid->val)
{
head = head->next;
return true;
}
return false;
}
bool chkPalindrome(ListNode* A) {
ListNode *head = A;
ListNode *mid = GetMidNode(A);
return RecurCheck(head, mid);
}
int main()
{
ListNode *a = new ListNode(1);
ListNode *b = new ListNode(2);
ListNode *c = new ListNode(3);
ListNode *d = new ListNode(2);
ListNode *e = new ListNode(1);
//ListNode *f = new ListNode(1);
a->next = b;
b->next = c;
c->next = d;
d->next = e;
//e->next = f;
cout << chkPalindrome(a) << endl;
return 0;
}