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?
方法一:
反序存一个新的链,在遍历两个链,进行比较,代码如下:
<pre name="code" class="cpp">bool isPalindrome(ListNode* head) {
stack<ListNode*> llist;
auto current=head;
while(current!=NULL){
llist.push(current);
current=current->next;
}
current=head;
while(llist.size()!=0&¤t!=NULL){
if(llist.top()->val==current->val){ current=current->next;llist.pop();}
else return false;
}
if(llist.size()==0&¤t==NULL) return true;
else return false;
}
很明显,空间复杂度为O(1),不是很好的算法。
方法二:
先找到链的中间,再把后半段翻转,两个指针一个从头一个从中间,遍历比较判断。找到链的中间用快慢指针,反转链可以用之前的题的代码。
<span style="color:#333333;">/**
* 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) {
if(head==NULL||head->next==NULL) return true;
auto fast=head;
auto slow=head;
while(fast->next!=NULL&&fast->next->next!=NULL){
fast=fast->next->next;
slow=slow->next;
}
slow=slow->next;
slow=reverseList(slow);
auto last=head;
</span><span style="color:#cc0000;">while(slow!=NULL)</span><span style="color:#333333;">{
if(last->val!=slow->val) return false;
slow=slow->next;last=last->next;
}
return true;
}
ListNode* reverseList(ListNode* head){
if(head==NULL) return NULL;
ListNode* next=NULL;
ListNode* pre=NULL;
while(head!=NULL){
next=head->next;
head->next=pre;
pre=head;
head=next;
}
return pre;
}
};</span>
由于链中节点的个数可能是偶数也可能是奇数,所以以slow做头的后半段链表的大小是小于等于前半段的,所以while中的判断条件是slow!=NULL。