链接
https://leetcode-cn.com/problems/palindrome-linked-list/
前言
链表系列还需多做题巩固
题目
请判断一个链表是否为回文链表。
- 示例1
输入: 1->2
输出: false
- 示例2
输入: 1->2->2->1
输出: true
关键
思路1
- 利用数组
class Solution(object):
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if not (head and head.next):
return True
arr,i = [],0
# 申请一个数组,然后把元素都放到数组中
while head:
_,head = arr.append(head.val),head.next
j = len(arr)-1
# 用i和j两个指针,一个往后,一个往前,不断迭代
# 如果i的值不等于j说明不是回文,反之是回文
while i<j:
if arr[i]!=arr[j]:
return False
i,j = i+1,j-1
return True
思路2
- 双指针+反转
class Solution(object):
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
# 边界条件不用忘记了
if not (head and head.next):
return True
p = ListNode(-1)
p.next,low,fast = head,p,p
# 快慢指针不断迭代,找到中间节点
while fast and fast.next:
low,fast = low.next, fast.next.next
cur,pre = low.next,None
low.next = None
#将链表一分为二之后,反转链表后半部分
while cur:
cur.next,pre,cur = pre,cur,cur.next
a,b = p.next,pre
# 将链表前半部分和 反转的后半部分对比
while b:
if a.val!=b.val:
return False
a,b = a.next,b.next
return True
- 快慢指针找中点
思路3
- 双指针反转链表
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
if not head:
return True
fast = slow = head
# 找中间点
while fast.next and fast.next.next:
fast = fast.next.next
slow = slow.next
#分离链表
pre = None
cur = slow.next
slow.next = None
# 反转后半段链表
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
# 判断是否对称
while pre:
if head.val != pre.val:
return False
head = head.next
pre = pre.next
return True
过程有点复杂,找中点(不熟悉)+反转+比较