题目:
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
过程:
由于是单链表,我们无法从尾向后去遍历,因此我们可以
- 先得到链表的中间结点 mid。
- 将 mid 所指的链表后面的结点逆置(逆置在我之前的博客写了 反转链表)
- 这样就可以得到类似 1 -> 2 -> 3 <-2 <- 1 的链表
- 令cur 指向链表头结点,curR 指向链表的为结点(也就是3.中位置末的结点1),cur从左向右遍历,curR从右向左遍历,依次比较即可。
代码:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* cur = head;
int len = 0;
while (cur)
{
len++;
cur = cur->next;
}
cur = head;
len = len /2;
while (len--)
{
cur = cur->next;
}
return cur;
}
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode* cur = head;
struct ListNode* newhead = NULL;
while (cur)
{
struct ListNode* next = cur->next;
cur->next = newhead;
newhead = cur;
cur = next;
}
return newhead;
}
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
struct ListNode* mid = middleNode(A);
struct ListNode* rHead = reverseList(mid);
struct ListNode* curA = A;
struct ListNode* curB = rHead;
while (curA && curB)
{
if (curA->val == curB->val)
{
curA = curA->next;
curB = curB->next;
}
else
{
return false;
}
}
return true;
}
};