LeetCode234. 回文链表
方法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
"""
# 转成列表
stack=[]
while head:
stack.append(head.val)
head=head.next
# 左右双指针逼近
l=0
r=len(stack)-1
while l<=r:
if stack[l]!=stack[r]:
return False
else:
l+=1
r-=1
return True
方法2:反转后半部分链表后,逐个比较节点值
- 边界条件(如[] 或者 [2])直接返回
- 快慢指针找中点
- 反转以slow为开头的链表
- 只需判断p2存在时,p1是否等于p2
以偶数为例(奇数类似)
链表:1->2->2->1
下标:[0] [1] [2] [3]
- 快慢指针后,slow指向第二个2(下标为[2]),fast已跳出链表
- 此时slow后面的链表为
2->1
。反转时,2(下标为[2])指向prev的None,1指向2。最后有None<-2<-1
(此时prev在下标[3]处)。(注意:此时前半段中,下标为[1]的节点2仍然指向下标为[2]的节点2) - 此时,以head开头的p1为
1->2->2->None
,以prev开头的p2为None<-2<-1
,所以只需判断p2存在时,p1是否等于p2。
# 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
"""
# 边界条件,直接跳出,如[] 或者 [2]
# if not head or not head.next: return True
if not (head and head.next): return True # 必须有括号,and后取其反
# 快慢指针找中点
slow=head
fast=head
while fast and fast.next:
slow=slow.next
fast=fast.next.next
# 反转以slow开始的后半部分链表
prev = None
cur=slow
while cur:
cur.next,prev,cur=prev,cur,cur.next
p1=head
p2=prev
# 只需判断p2存在时,p1是否等于p2
while p2:
if p1.val!=p2.val:
return False
p1=p1.next
p2=p2.next
return True