参考链接:234. Palindrome Linked List [easy] (Python)
这个博主总结了三种解法:
- 将单链表的节点值记录到一个数组中,判断数组是否回文;(或通过一次遍历将单链表拓展成双向链表,再判断是否回文。 )——时间 O(n),空间O(n)
- 判断回文主要是前半部分和后半部分的比较,若能将前半部分压栈,再依次出栈与后半部分比较,则可判断是否回文。——时间 O(n),空间O(n/2)
- 类似思路二,判断回文主要是前半部分和后半部分的比较,若能将后半部分反转(仍然是单链表),则可以方便的判断回文。——时间 O(n),空间O(1)
实验发现,该博主提供的代码存在bug,但是思路没问题,遂修改汇总一番
主要用到的知识点为:
- “快慢指针” ,关于快慢指针的原理与应用,可以参考关于快慢指针的若干应用详解
- “翻转链表”,可以参考链表翻转的图文讲解(递归与迭代两种实现)
我实现了第三种,时间复杂度 O(n),空间复杂度O(1)的算法,先找到中位节点,然后翻转后半部分,然后逐一比较。代码如下:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if (head is None) or (head.next is None):
return True
# slow fast pointer, find the middle point
middleNode = self.middleNode(head)
# reverse the last half of the linkList
slow = self.reverseList(middleNode)
while slow is not None:
if head.val != slow.val:
return False
head = head.next
slow = slow.next
return True
def reverseList(self, head):
if head is None:
return None
present = head
new_head = None
while present is not None:
cur = present.next
present.next = new_head
new_head = present
present = cur
return new_head
def middleNode(self, head):
fast = head
slow = head
while (fast is not None) and (slow is not None):
if fast.next is None:
return slow
elif (fast.next is not None) and (fast.next.next is None):
return slow.next
else:
fast = fast.next.next
slow = slow.next