题目
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?
题意分析
判断一个链表是否是回文链表。
所谓回文,即从左往右和从右往左读都是一样的。例如:
“abcdefgfedcba”
1->2->3->3->2->1
我们现在要做的,就是判断给定的链表是否满足这个特性。
这题还有一个难点,就是时间复杂度与空间复杂度的限制。特别是空间复杂度限制太严格了。
解法一:
使用一个栈把遍历一遍的节点全存下来.
class Solution { public: bool isPalindrome(ListNode* head) { ListNode *l=head; stack<ListNode *> s; while(head) { s.push(head); head=head->next; } int n=s.size()/2; for(int i=0;i<n;i++) // while(!s.empty()) { ///cout<<i<<" "<<s.size()/2<<endl; cout<<s.top()->val<<endl; cout<<l->val<<endl; if(s.top()->val==l->val) { l=l->next; s.pop(); } else return false; } return true; } };
但是空间复杂度为N, 因此考虑怎么减少空间复杂度,
解法二: 使用递归的方法,虽然有局部的空间占用,但是可以规避空间复杂度的问题:
- 终止条件:到达中间节点
- 判断 链表: n2->n3->n4->...->n(size()-1)&&n1==n(size());
ListNode* temp=head; int length=0; while(temp) { length++; temp=temp->next; } int mid=(length+1)/2; if(head==NULL||head->next==NULL) return true; ListNode * result=isEqual(head,1,mid,length); if(result!=NULL) { return true; } else return false; } ListNode * isEqual(ListNode *head, int index,int mid, int length) { if(mid==index&& length%2==1) { return head->next; } else if(mid==index && length%2==0) { if(head->val==head->next->val) { if(head->next->next!=NULL) return head->next->next; else return head->next; } else return NULL; } else { ListNode *t=isEqual(head->next,(index+1),mid,length); if(t==NULL) return NULL; else if(head->val==t->val) { if(t->next!=NULL) return t->next; else return t; } else return NULL; }
解法三:
- 得到中点作为截止条件
- 将后半段链表逆序
- 遍历前半段与后半段
ListNode * reverse(ListNode * head, int mid) { while(mid!=0) { head=head->next; mid--; } ListNode * a=NULL; while(head!=NULL) { ListNode *t=head; head=head->next; t->next=a; a=t; cout<<a->val<<endl; // cout<<head->val<<endl; } return a; } bool isPalindrome(ListNode* head) { if(head==NULL||head->next==NULL) return true; int length=0; ListNode *c=head; while(c) { length++; c=c->next; } cout<<(length+1)/2<<endl; ListNode * a=reverse(head,(length+1)/2); while(a) { if(head->val==a->val) { head=head->next; a=a->next; } else return false; } return true; }