20.4.23 回文链表 简单 234
时间复杂度O(n²),空间复杂度O(1)
题目
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
解题思路
- 一开始只能想到暴力,用数组存起来;
- 看讨论看到了一边逆序一边检验,可是没看到快慢指针哈哈,快慢指针时间复杂度是O(n),我这种只看到了逆序没看到快慢指针的,是O(n²);
- 3种特殊情况,1、空指针,2、只有一个结点,3、奇数结点数的回文链表中间有三个相同的数
- 第一二种情况,简单排除就行了;
- 第三种情况,因为循环的时候并不知道结点数是奇数还是偶数,所以只能每次都判断比较该点的值与下一个点的值和下下个点的值;
- 只能感叹快慢指针才是最棒的选择,代码简单易懂,虽然我这种也能看懂,就是倒序的过程中加上两个判断和检验。
代码
/**
* 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 || !head->next) return true;
ListNode* pre=NULL, *curr=head;
while(curr){
ListNode *temp=curr->next;
curr->next=pre;
if(temp && curr->val==temp->val){
ListNode *left=curr, *right=temp;
while(left->val==right->val){
left=left->next;
right=right->next;
if(!left&&!right) return true;
if(!left || !right) break;
}
}
if(temp && temp->next && curr->val==temp->next->val){
ListNode *left=curr, *right=temp->next;
while(left->val==right->val){
left=left->next;
right=right->next;
if(!left&&!right) return true;
if(!left || !right) break;
}
}
pre=curr;
curr=temp;
}
return false;
}
};