题目
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?
Subscribe to see which companies asked this question
思路
我的思路
想了半天没有想出空间为1的解法,就用了最先考虑到的数据结构栈来实现了。首先定义两个快慢指针,从头开始遍历,将慢指针压进栈内,当快指针走到尾时,慢指针指向的就确定了中间位置。然后慢指针继续前进,同时和栈顶元素进行比较,如果不相等则返回false。
Hot 解法
开始都是使用快慢指针确定了中间位置,然后它实现了一个翻转链表的操作,将慢指针还未走过的链表翻转了,然后对翻转的链表和从头开始的链表进行比较。
代码
我的代码
bool isPalindrome(ListNode* head) {
if (!head) return true;
stack<ListNode*> st;
ListNode* fast=head;
ListNode* slow=head;
while (fast&&fast->next){
st.push(slow);
fast=fast->next->next;
slow=slow->next;
}
if (fast) slow=slow->next;
while (!st.empty() && slow->val==st.top()->val){
st.pop();slow=slow->next;
}
return st.empty();
}
Hot解法
bool isPalindrome(ListNode* head) {
if(head==NULL||head->next==NULL)
return true;
ListNode* slow=head;
ListNode* fast=head;
while(fast->next!=NULL&&fast->next->next!=NULL){
slow=slow->next;
fast=fast->next->next;
}
slow->next=reverseList(slow->next);
slow=slow->next;
while(slow!=NULL){
if(head->val!=slow->val)
return false;
head=head->next;
slow=slow->next;
}
return true;
}
ListNode* reverseList(ListNode* head) {
ListNode* pre=NULL;
ListNode* next=NULL;
while(head!=NULL){
next=head->next;
head->next=pre;
pre=head;
head=next;
}
return pre;
}
链表翻转
链表翻转就是一道比较经典的题目,此处是一个O(1)的实现。最重要最需要注意的两个地方是提前保存下一个节点(next)和保存翻转后的头结点(prev)。
ListNode* reverseList(ListNode* head) {
ListNode* pre=NULL;
ListNode* next=NULL;
while(head!=NULL){
next=head->next;
head->next=pre;
pre=head;
head=next;
}
return pre;
}
记忆小技巧:在while循环里一共四句话,最开始当然是要提前保存正常顺序下的下一个节点,可以发现它们都是收尾相接的,最后移动head到保存好的next节点。