目录:
目的
{1,2,2,1} true 是回文结构。
思路
这个任务是判断链表正序逆序是否完全一致。即判断这个链表是否是对称的。可以理解为双折叠手机,怎么折都有面。折叠手机左右两边大小一定是一样的对称的。
第一步:找到折叠的折痕(中点):
找中点:参考文章
力扣刷题TOP101:10.BM12 单链表的排序-优快云博客但是这里有个区别:fast从head开始,为什么?
1. fast = head:常用于需要将链表分成两半(左右相等或尽可能均等)或在奇偶长度中处理逻辑一致的场景。
2. fast = head.next:常用于需要知道链表前半部分终止位置的场景。
第二步:折叠右边(翻转链表的后半部分):
把手机的右半部分从折痕处翻转过来:参考文章
力扣刷题TOP101:1.BM1 反转链表-优快云博客
第三步:对比左右两边手机大小(对称性):
p1表示左边手机,p2代表右边手机(已反转后的)。
- 逐节点比较: 左边的节点值和右边对应节点值逐一比对。
- 如果左右存在任何不一致,直接返回
False
;如果所有大小都一致,说明手机是对称的。 - 对比时只需要遍历右半部分即可,因为反转后两部分长度相等。
复杂度
-
时间复杂度:O(n)
- 链表被遍历了几次,但总操作数量是线性的。。
-
空间复杂度:O(1)
- 使用了快慢指针和一些临时变量,没有额外的空间开销。
记忆秘诀
- 找到折痕:使用快慢指针找链表的中点。
- 折叠右侧:反转链表的后半部分。
- 对比两边:逐节点检查两边是否完全对称。
python代码
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类 the head
# @return bool布尔型
#
class Solution:
# 工具函数:使用快慢指针法找到链表的中点
def getMiddle(self, head: ListNode) -> ListNode:
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
# 工具函数:反转链表
def reverse(self, head: ListNode) -> ListNode:
prev = None
cur = head
while cur:
next_node = cur.next
cur.next = prev
prev = cur
cur = next_node
return prev
# 主函数:判断链表是否为回文
def isPail(self , head: ListNode) -> bool:
if not head or not head.next:
return True # 空链表或单节点链表,直接返回True
# 使用快慢指针找到链表的中点
mid = self.getMiddle(head)
# 反转链表的后半部分
reversed_half = self.reverse(mid)
# 比较链表的前半部分和反转后的后半部分
first_half, second_half = head, reversed_half
while second_half:
if first_half.val != second_half.val:
return False
first_half = first_half.next
second_half = second_half.next
# 链表是回文,返回True
return True
* 欢迎大家探讨新思路,能够更好的理解和记忆