题目
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:

输入:head = [1,2,2,1] 输出:true
示例 2:

输入:head = [1,2] 输出:false
提示:
- 链表中节点数目在范围
[1, 105]内 0 <= Node.val <= 9
思路
找中点 + 反转链表
(1)遍历链表,利用快慢指针找链表的中点
fast一次走两步,slow一次走一步(x = vt,fast = 2 * t,slow = 1 * t,当fast走完链表,意味着slow刚好走了链表的一半)
(2)找到中点后,把中点后的链表部分反转过来
利用“206.反转链表”实现,即,记录后一个元素,不断修改当前元素和前一个元素的指针,直至当前元素都处理完
(3)反转之后就可以比较了,当然,存在奇数和偶数长度的问题,当我们找中点时,链表后半部分的长度一定是<=前半部分的,所以只需要遍历后半部分,和前半部分不断比较即可~
举例:
1 2 3 2 1:找到的中点是3,反转之后左边是123,右边是12,以右边为准对比
1 2 3 3 2 1:找到的中点是左3,反转之后左边是123,右边是123,以右边为准对比
代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def isPalindrome(self, head: Optional[ListNode]) -> bool:
slow, fast = head, head # 快慢指针找中点
while fast and fast.next:
slow = slow.next
fast = fast.next.next
pre, curr = None, slow # 反转链表
while curr:
next_tmp = curr.next
curr.next = pre
pre = curr
curr = next_tmp
left, right = head, pre # 左边和右边进行对比(注意右边的头结点是pre而不是slow)
while right: # 右边长度≤左边,以右边为基准
if left.val != right.val:
return False
left = left.next
right = right.next
return True
674

被折叠的 条评论
为什么被折叠?



