题目
编写一个函数,检查输入的链表是否是回文的。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
分析: 判断单链表是否是回文链表,及链表的正序等于反序,最容易想到的一种方式是复制一份相同的链表,进行反转后逐节点比较
方法一:复制链表进行反转比较
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
#先复制链表,再反转链表,比较两个链表是否相等
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
if head == None or head.next == None:
return True
new_head = ListNode(head.val)
tmp_new_head = new_head
tmp_head = head
while tmp_head.next != None:
tmp_head = tmp_head.next
tmp_new_head.next = ListNode(tmp_head.val)
tmp_new_head = tmp_new_head.next
head_reverse = None
cur_node = head
while cur_node != None:
tmp_node = cur_node.next
cur_node.next = head_reverse
head_reverse = cur_node
cur_node = tmp_node
while new_head != None and head_reverse != None:
if new_head.val == head_reverse.val:
new_head = new_head.next
head_reverse = head_reverse.next
else:
return False
return True
方法二:回文链表节点值基于中心点对称,因此可以找到链表的中心节点,然后反转后半部分链表,与前半部链表进行比较即可,需要注意链表奇偶长度的处理,此方法时间复杂度是O(n), 空间复杂度O(1)
class Solution1:
def isPalindrome(self, head: ListNode) -> bool:
if head == None or head.next == None:
return True
fast = head
slow = head
while fast != None and fast.next != None:
slow = slow.next
fast = fast.next.next
if fast != None:
slow = slow.next
# 反转slow后部分的链表,可以用遍历,也可以用递归
'''
new_head = None
while slow != None:
tmp_node = slow
slow = slow.next
tmp_node.next = new_head
new_head = tmp_node
'''
#采用递归的方式反转链表
new_head = self.reverse(slow)
while new_head != None:
if head.val != new_head.val:
return False
head = head.next
new_head = new_head.next
return True
def reverse(self, head):
if head.next == None:
return head
last_node = self.reverse(head.next)
head.next.next = head
head.next = None
return last_node
方法三:借助二叉树的后序遍历操作,链表也可以进行,链表兼具递归结构,树结构不过是 链表的衍⽣,因此,可以通过递归的方式实现链表的后序遍历,实现后序遍历后便可以进行头节点和尾节点的双指针操作,模拟列表两端靠拢判断
#采用后续遍历
class Solution2:
def isPalindrome(self, head: ListNode) -> bool:
if head == None or head.next == None:
return True
head, judge = self.recursive(head, head)
return judge
def recursive(self, head, left):
if left == None:
return head, True
head, judge = self.recursive(head, left.next)
if head.val == left.val and judge:
return head.next, judge
else:
return head, False