Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2
Output: false
Example 2:
Input: 1->2->2->1
Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
题目链接:https://leetcode.com/problems/palindrome-linked-list/
先用最拙劣的办法,我去复旦保研机试得到最大的教训就是,不管复杂度,你快速实现功能再说,敏捷编程一点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
vector<int> tmp;
while(head)
{
tmp.emplace_back(head->val);
head=head->next;
}
int n=tmp.size();
for(int i=0;i<n/2;i++)
{
if(tmp[i]!=tmp[n-i-1])
{
return false;
}
}
return true;
}
};
好方法就是先 快慢指针 然后反转链表。从慢指针slow的next开始,给后续的链表反转过来,这样链表最后的节点元素跑到前面来了。这样pre和最初的链表头head开始一一比较就行了。一遍过很开心
注意:反转的只是链表的后半部分,pre是反转部分链表的头结点。记住反转链表的头结点是pre,不是nxt,nxt是NULL时,刚好退出。
我代码里这样写,没有把pre赋值给slow->next,所以执行后的链表,从头开始遍历的结果会是:5,4,3,2,1,1->NULL.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head==NULL||head->next==NULL)
return true;
ListNode *fast=head->next,*slow=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
ListNode *cur=slow->next,*pre=NULL,*nxt=NULL;
while(cur)
{
nxt=cur->next;
cur->next=pre;
pre=cur;
cur=nxt;
}
// slow->next=pre;没必要赋值给slow->next了,直接用pre开始就行了
bool flag=true;
while(head&&pre&&flag)
{
if(head->val!=pre->val)
{
flag=false;
}
else
{
head=head->next;
pre=pre->next;
}
}
return flag;
}
};