Leetcode刷题(16) 回文链表系列
具体方法参考: labuladong的如何判断回文链表, 以下python的重写
234. 回文链表
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
# 单链表的后续遍历
class Solution(object):
def __init__(self):
self.left = None
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
self.left = head
# left ---> <---right
def traverse(right):
# base case
if right == None:
return True
else:
res = traverse(right.next)
# 后续遍历right
res = res and right.val == self.left.val
self.left = self.left.next
return res
return traverse(head)
方法二:
先找中点--->翻转后半段链表--->比较判断
# 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
"""
# 找到中点
def findmidnode(head):
slow = head
fast = head
while(fast != None and fast.next != None):
fast = fast.next.next
slow = slow.next
if fast!= None:
slow = slow.next
return slow
# 将中点包括中点之后的链表原地翻转形成一小段新的链表
def reverse(mid):
# base case
pre = None # cur指向前节点(翻转时第一个前节点是None)
cur = mid # 要翻转的节点
while(cur!=None):
# 记录下cur的next, 因为之后cur的next的指向会被修改
nex = cur.next
cur.next = pre
# update per and cur to next iteration
pre = cur
cur = nex
return pre
# 遍历判断每个元素是否相等
def traverse(right):
left = head
while(right!=None):
if left.val != right.val:
return False
left = left.next
right = right.next
return True
mid = findmidnode(head)
right = reverse(mid)
return traverse(right)
5. 最长回文子串
具体方法参考labuladong的如何寻找最长回文子串
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
# 找到以[l, r]为中点的最长回文子串
def palindrome(l, r):
while(l >= 0 and r <= size-1 and s[l] == s[r]):
l -= 1
r += 1
return s[l+1: r]
size = len(s)
res = ""
for i in range(size):
# s有奇数个
l1 = palindrome(i, i)
# s有偶数个
l2 = palindrome(i, i + 1)
if len(l1) > len(l2):
if len(l1) > len(res):
res = l1
else:
if len(l2) > len(res):
res = l2
return res
92. 反转链表 II
方法参考递归反转链表的一部分
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def __init__(self):
self.successor = None
def reverseBetween(self, head, m, n):
"""
:type head: ListNode
:type m: int
:type n: int
:rtype: ListNode
"""
successor = None # 这个是全局的没错
print(id(successor)) # 输出地址进行校验
def reverseN(head, N):
# base case
if N == 1:
# 记录一下递归末端的后驱,之后新end要指向这个后驱
successor = head.next # 但是在这被修改成局部的了, 全局变量的同名变量successor所指向的内存已经被改变了
print(id(successor)) # 输出地址可以校验
self.successor = head.next
return head
else:
last = reverseN(head.next, N-1)
head.next.next = head
# head.next = successor # 所以递归到这会报错UnboundLocalError: local variable 'successor' referenced before assignment
head.next = self.successor
return last # last是新的head, 一直返回其即可
def reverseBetween(head, M, N):
# basecase
if M == 1:
return reverseN(head, N)
# 一直递归到basecase就能启用reverseN:从head开始反转N个node
head.next = reverseBetween(head.next, M-1, N-1) # 然后把next指向反转后的新head
return head
return reverseBetween(head, m, n)