请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
这个题稍微有些复杂,首先一定得找到中点,所以还是使用快慢指针,当快指针到达终点时,慢指针就到中点了,然后需要用栈来存储慢指针遍历的元素,因为要与后面一半的链表值对比需要将前面一半反向。
C++源代码:
/**
* 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 *slow = head, *fast = head;
stack<int> s;
s.push(head->val);
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
s.push(slow->val);
}
if (!fast->next) s.pop();
while (slow->next) {
slow = slow->next;
int tmp = s.top(); s.pop();
if (tmp != slow->val) return false;
}
return true;
}
};
在进阶中提出了要求需要使用O(1)空间,所以不可以使用栈了,这样就只能把前面或者后面的链表反转然后进行对比即可,这里将后面的链表进行反转,反转的思路循环将后一个指针指向前面一个指针,而最前面的指针将指向最后(在中间过程中是让它不停指向之后指针的下一个)。所以需要一个last来存储最开始的位置,当这个位置指向了空,说明后面的链表已经反转完毕。
python3源代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head==None or head.next==None: return True
slow = head
fast = head
while fast.next!=None and fast.next.next!=None:
slow = slow.next
fast = fast.next.next
last = slow.next
pre = head
while last.next!=None:
tmp = last.next
last.next = tmp.next
tmp.next = slow.next
slow.next = tmp
while slow.next!=None:
slow = slow.next
if pre.val != slow.val: return False
pre = pre.next
return True