[链表] LeetCode 234. 回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
首先求链表的中点slow,然后反转从slow开始的后半部分的链表
再从头比较
不用担心正向会是全部链表,在进行反转的第一步时就将中间节点的next设置为null了,这也就是为何不能在找中点的同时反转链表,因为会切断链接
时间O(n),空间O(1)
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode *re = new ListNode(0);
ListNode *q,*s = head;
ListNode *slow = head;
ListNode *fast = head;
while(fast&&fast->next){
slow = slow->next;
fast = fast->next->next;
}
while(slow){ //slow链表中点
q = slow->next;
slow->next = re->next;//第一次执行切断和前半部分链表的链接
re->next = slow;
slow = q;
}
re = re->next; //re是反转后的头节点
while(re){ //s是正向的头节点
if(re->val!=s->val)
return false;
re=re->next;
s=s->next;
}
return true;
}
};
递归写法
利用程序调用栈逆序返回的特点,和开头对比,注意在调用处加上判断,如果返回一次false就次次返回false
时间O(n),空间O(n)
class Solution {
public:
ListNode *q;//保存首节点
bool isPalindrome(ListNode* head) {
if(!head) return true;
q = head;
return comp(head);
}
bool comp(ListNode *head){
if(head->next)
if(!comp(head->next))
return false;
if(q->val!=head->val) return false;
q=q->next;
return true;
}
};