一、题目
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
二、解题思路
1.通过一个列表来储存单链表。因为python对列表的支持可以很容易得到倒序。所以可以直接通过正序和倒序来判断是否为回文。优点:思路清晰,简单。缺点:需要额外存储空间。
2.针对官方解释的理解:因为回文的特点是可以从正中间截断,前后对称。那么从这个角度思考,可以通过找到中点,然后反转后半段链表(通过改变指针)来看前后两段是否相同,如果完全一致则证明是回文。优点:不需要额外存储空间,符合题目进阶要求。缺点:代码多,复杂,很难想到这种方法。
三、代码
1、 O(n) 时间复杂度和 O(n) 空间复杂度
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
values=[]
current=head
while current is not None:
values.append(current.val)
current=current.next
return values==values[::-1]
- 官方代码: O(n) 时间复杂度和 O(1) 空间复杂度
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
if head is None:
return True
# Find the end of first half and reverse second half.
first_half_end = self.end_of_first_half(head)
second_half_start = self.reverse_list(first_half_end.next)
# Check whether or not there's a palindrome.
result = True
first_position = head
second_position = second_half_start
while result and second_position is not None:
if first_position.val != second_position.val:
result = False
first_position = first_position.next
second_position = second_position.next
# Restore the list and return the result.
first_half_end.next = self.reverse_list(second_half_start)
return result
def end_of_first_half(self, head):
fast = head
slow = head
while fast.next is not None and fast.next.next is not None:
fast = fast.next.next
slow = slow.next
return slow
def reverse_list(self, head):
previous = None
current = head
while current is not None:
next_node = current.next
current.next = previous
previous = current
current = next_node
return previous