题目描述:
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
方法一:
将链表的值转化为一个数组。
两个指针从数组的首尾分别开始移动,在相遇之前,如果值一旦不等,则不是回文列表。
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
p = head
lst = []
while p:
lst.append(p.val)
p = p.next
i = 0
j = len(lst)-1
while i <= j:
if lst[i] != lst[j]:
return False
i = i + 1
j = j - 1
return True
你能否用 O(n)
时间复杂度和 O(1)
空间复杂度解决此题?
方法二:
将列表一分为二,后半部分进行反转,就可以进行ListNode与ListNode之间的比较。
那么问题便转化为,如何求出链表的中间位置:
我们考虑使用快慢指针,快指针的速度是慢指针的两倍。
当链表的结点数是偶数个时,当快指针 == None时,慢指针刚好指向第二段链表的头结点。
当链表的结点数是奇数个时,当快指针.next == None时,慢指针.next为第二段链表的头结点,为了翻转后段链表,我们向后移动一次。
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
fast = head
slow = head
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
# 如果链表个数是奇数 就把slow结点再后裔一位
if fast is not None:
slow = slow.next
slow = self.reverseList(slow)
# fast指针指回头结点
fast = head
while slow:
if fast.val != slow.val:
return False
# 虽然仍然叫fast但已经不快了 依次比较
fast = fast.next
slow = slow.next
return True
def reverseList(self, head: ListNode) -> ListNode:
preNode = None
CurrNode = head
while CurrNode is not None:
# 存储当前结点的下一个结点
nextNode = CurrNode.next
# 列表反转
CurrNode.next = preNode
# 两个指针都向后移动
preNode = CurrNode
CurrNode = nextNode
return preNode
关于链表的reverse:
算法练习——反转列表 leetcode.206 python_tangchujiang的博客-CSDN博客https://blog.csdn.net/tangchujiang/article/details/123385306?spm=1001.2014.3001.5502