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?
/** * Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
/*algorithm
1, convert list to array, check array result
O(n)space, O(n)time
*/
bool isPalindrome(ListNode* head) {
vector<int>list;
ListNode *p = head;
while(p){
list.push_back(p->val);
p = p->next;
}
//check Palindrome
for(int i = 0,j = (int)list.size() - 1;i < j;++i,--j){
if(list[i] != list[j])return false;
}
return true;
}
};
/*algorithm 2
if we can modify list, separate at middle, reverse the latter
compare the former and the latter element,
restore the list
O(n)space, O(1)time
eg, 1->2->2->1 ==>1->2 2->1 ==>1->2 1->2
*/
ListNode* reverse(ListNode* list){
ListNode dummy(0),*p = list,*next;
while(p){
next = p->next;
p->next = dummy.next;
dummy.next = p;
p = next;
}
return dummy.next;
}
bool isPalindrome(ListNode* head) {
if(!head)return true; //lenght ==0
bool ret = true;
ListNode *q,*p = head;
ListNode dummy(0);dummy.next = head;
ListNode *faster = &dummy,*slower = &dummy;
//x->1->2 faster:2 slower:1
//x->1->2->3 faster:3, slower:2
//make sure slower always point to middile element no matter even or odd
while(faster->next){
faster = faster->next;
if(faster && faster->next)faster = faster->next;
slower = slower->next;
}
//reah here, reverse the latter part[slower + 1, faster]
ListNode* newHead = reverse(slower->next);
slower->next = NULL;
//compare element one by one
//in odd node, the former list will have one more node than latter
//so use the latter to compare
q = newHead;
while(q){
if(q->val != p->val){
ret = false;
break;
}
q = q->next;
p = p->next;
}
//restore old list
slower->next = reverse(newHead);
return ret;
}
/*algorithm
3, recursive version, use bottom-up way
O(n)space, O(n)time
*/
/*head: pointer to first part
tail: pointer to second part
result: head<->tail comparison result
*/
void isPalindromeSub(ListNode* &head,ListNode* tail,int &result){
if(!tail)return;
//if(head == tail && result != -1)return;
isPalindromeSub(head,tail->next,result);
if(result == 0)return;
result = head->val == tail->val;
head = head->next;
}
bool isPalindrome(ListNode* head) {
if(!head)return true;
ListNode* tail = head;
int result = -1;
isPalindromeSub(head,tail,result);
return result;
}