Leetcode刷题(16) 回文链表系列

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)
        
        

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值