题目要求
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
题解
献丑法
由简单题组成的简单题,思路很顺畅,一写就出错,最后还用playgroud辅助检查的我真是菜的真实。
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(!head||!head->next) return true; // 0,1个元素返回真
// 快慢指针找中间点
ListNode *fast=head,*slow=head;
//这种判断条件下奇数个元素会停在中间,偶数个则会停在前半部分
while(fast->next&&fast->next->next){
slow=slow->next;
fast=fast->next->next;
}
//把后半部分翻转一下
ListNode *pre=nullptr;
ListNode *cur=slow->next; //如果是偶数个,show正常后移,如果奇数个则此时后移为跳过中间元素
while(cur){
ListNode *tmp=cur->next;
cur->next=pre;
pre=cur;
cur=tmp;
}
//这里注意下反转后的部分表头为pre
for(cur=pre;cur;head=head->next,cur=cur->next){
if(head->val!=cur->val)
return false;
}
return true;
}
};
执行用时 | 内存消耗 |
---|---|
24 ms | 12.6 MB |
以下转自:
https://leetcode-cn.com/problems/palindrome-linked-list/solution/hui-wen-lian-biao-1zhan-2kuai-man-zhi-zhen-fan-zhu/
找中间点反转合一法
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(!head || !head->next)
return 1;
ListNode *fast = head, *slow = head;
ListNode *p, *pre = NULL;
while(fast && fast->next){ //这里和我的判断条件不同所以有下面判断奇偶的那部分
p = slow; //这种判断条件下奇数个元素会停在中间,偶数个则会停在后半部分
slow = slow->next; //快慢遍历
fast = fast->next->next;
p->next = pre; //翻转
pre = p;
}
if(fast) //奇数个节点时跳过中间节点
slow = slow->next;
while(p){ //前半部分和后半部分比较
if(p->val != slow->val)
return 0;
p = p->next;
slow = slow->next;
}
return 1;
}
};
执行用时 | 内存消耗 |
---|---|
22 ms | 12.3 MB |
栈
正反一样。
class Solution {
public:
bool isPalindrome(ListNode* head) {
stack<int> s;
ListNode *p = head;
while(p){
s.push(p->val);
p = p->next;
}
p = head;
while(p){
if(p->val != s.top()){
return 0;
}
s.pop();
p = p->next;
}
return 1;
}
};
执行用时 | 内存消耗 |
---|---|
24 ms | 13.6 MB |