力扣刷题(第五十八天)
灵感来源
- 保持更新,努力学习
- python脚本学习
回文链表
解题思路
- 使用快慢指针找到链表的中间节点。
- 反转链表的后半部分。
- 比较前半部分和反转后的后半部分是否相同。
- (可选)恢复链表的原始结构。
class Solution:def isPalindrome(self, head: ListNode) -> bool:if not head or not head.next:return True# 使用快慢指针找到中间节点slow, fast = head, headwhile fast.next and fast.next.next:slow = slow.nextfast = fast.next.next# 反转后半部分链表second_half = self.reverseList(slow.next)# 比较前半部分和反转后的后半部分first_ptr = headsecond_ptr = second_halfresult = Truewhile result and second_ptr:if first_ptr.val != second_ptr.val:result = Falsefirst_ptr = first_ptr.nextsecond_ptr = second_ptr.next# 恢复链表(可选)slow.next = self.reverseList(second_half)return resultdef reverseList(self, head: ListNode) -> ListNode:prev = Nonecurr = headwhile curr:next_node = curr.next # 保存下一个节点curr.next = prev # 反转指针prev = curr # 移动prev指针curr = next_node # 移动curr指针return prev
逐行解释
class Solution:def isPalindrome(self, head: ListNode) -> bool:# 处理边界情况:空链表或只有一个节点的链表是回文if not head or not head.next:return True# 步骤1:使用快慢指针找到链表的中间节点slow, fast = head, headwhile fast.next and fast.next.next:slow = slow.next # 慢指针每次移动一步fast = fast.next.next # 快指针每次移动两步# 此时slow指针位于中间节点(奇数长度)或前半部分的最后一个节点(偶数长度)# 例如:1->2->3->2->1,slow指向3;1->2->2->1,slow指向第一个2# 步骤2:反转后半部分链表second_half = self.reverseList(slow.next)# 步骤3:比较前半部分和反转后的后半部分first_ptr = head # 前半部分的起始指针second_ptr = second_half # 后半部分的起始指针(已反转)result = True # 标记是否为回文while result and second_ptr:if first_ptr.val != second_ptr.val:result = Falsefirst_ptr = first_ptr.nextsecond_ptr = second_ptr.next# 步骤4:恢复链表(可选,题目不要求,但实际应用中可能需要保持链表原始结构)slow.next = self.reverseList(second_half)return resultdef reverseList(self, head: ListNode) -> ListNode:# 反转链表的辅助函数prev = Nonecurr = headwhile curr:next_node = curr.next # 保存下一个节点curr.next = prev # 当前节点指向前驱节点prev = curr # 前驱节点后移curr = next_node # 当前节点后移return prev # 返回新的头节点