题目:
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?
Tags: Linked List Two Pointers
Similar: Problems (E)Palindrome Number, (E)Valid Palindrome, (E)Reverse Linked List
分析:
算法流程:
(1)得到链表的中间位置
(2)反转后半段链表(如果链表长度为奇数,后半段链表不包括中间位置那个点)
(3)前半段和反转后的后半段一一比较,直到出现值不等的情况,或者后半段全部匹配时,结束。
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode* middle,*current;
if(head==NULL)
return true;
if(head->next==NULL)
return true;
/*
//求middle的第一种方法 算法测试共用时32ms
//第一步:统计list的长度
int size = 0;
current = head;
size = 1;
while(current->next!=NULL)
{
current = current->next;
++size;
}
//第二步:移动middle使其指向中间位置
//若size为偶数,middle指向第size/2+1个元素;若size为奇数,middle指向size/2+2个元素。
int m = (size%2==1)?(size/2+2):(size/2+1);
middle = head;
for(int i=1;i<m;++i)
middle = middle->next;
*/
//求middle的第二种方法 算法测试共用时28ms
middle = current = head;
while(current!=NULL)
{
middle = middle->next;
current = current->next;
if(current)
current = current->next;
}
//反转(reverse)后半部分
middle = reverseList(middle);
//回文比较
int flag = 0;
current = head;
while(middle!=NULL)
{
if(middle->val==current->val)
{
middle = middle->next;
current = current->next;
}
else
{
flag = 1;
break;
}
}
if(flag==1)
return false;
else
return true;
}
//Reverse Linked List
ListNode* reverseList(ListNode* head) {
if(head==NULL)
return head;
ListNode* tail = head;
ListNode* temp;
while( tail->next != NULL )
{
temp = head;
head = tail->next;
tail->next = head->next;
head->next = temp;
}
return head;
}
};