题目描述:
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
----------------------------------------------------------------------------------------------------------------------------
由于单链表不支持反向查找,因此不能像数组一样直接一个指针从前往后,一个指针从后往前。但是单链表却可以在线性时间内逆序并且不需要额外的空间,因此这道题的思路就是将链表一分为二,将后半部分进行逆序,然后比较前半部分和逆序后的链表是否值全部相等。但是需要注意的是要对链表长度是偶数和奇数进行判断,奇数的话,中间节点不需要判断。
现将代码粘贴如下:
class Solution {
public:
bool isPalindrome(ListNode* head) {
//可以将链表平均截成两段,将一段进行逆序,然后再遍历两个链表,看是否相等
//当链表节点个数为奇数2n+1时,中间节点省略,前半部分1-n, 后半部分n+2到2n+1
//当链表个数为偶数2n时,前面的n个节点不变,最后一个节点的next变为NULL,第n+1各节点开始逆序
if(head == NULL || head->next == NULL) //空节点或者只有一个节点肯定为回文
return true;
int length=0;
ListNode *p=head;
ListNode *head2 = head;
while(p != NULL)
{
length++;
p = p->next;
}
if(length%2 == 0) //偶数
{
for(int i=0; i<length/2; i++)
head2 = head2->next;
}
else //奇数
{
for(int i=0; i<length/2; i++)
head2 = head2->next;
head2 = head2->next; //还要往后挪一位
}
head2 = reverseList(head2); //将后面的链表进行逆序
for(int i=0; i<length/2; i++)
{
if(head->val != head2->val)
return false;
else
{
head = head->next;
head2 = head2->next;
}
}
return true;
}
ListNode* reverseList(ListNode *head)
{
if(head == NULL || head->next == NULL) //空节点或者一个节点,直接返回
return head;
ListNode *pre = NULL;
ListNode *cur = head;
ListNode *after = head->next;
while(after->next != NULL)
{
cur->next = pre;
pre = cur;
cur = after;
after = after->next;
}
//最后还剩下最后两个节点没有逆序
cur->next = pre;
after->next = cur;
return after;
}
};