回文算法总结

回文算法总结

最长回文子串

#
# @lc app=leetcode.cn id=5 lang=python3
#
# [5] 最长回文子串
#

# @lc code=start
class Solution:
    def longestPalindrome(self, s: str) -> str:
        size = len(s)
        if size < 2:
            return s
        
        # 至少是 1
        max_len = 1
        res = s[0]

        for i in range(size):
            palindrome_odd, odd_len = self.__center_spread(s, size, i, i)
            palindrome_even, even_len = self.__center_spread(s, size, i, i + 1)

            # 当前找到的最长回文子串
            cur_max_sub = palindrome_odd if odd_len >= even_len else palindrome_even
            if len(cur_max_sub) > max_len:
                max_len = len(cur_max_sub)
                res = cur_max_sub

        return res

    def __center_spread(self, s, size, left, right):
        """
        left = right 的时候,此时回文中心是一个字符,回文串的长度是奇数
        right = left + 1 的时候,此时回文中心是一个空隙,回文串的长度是偶数
        """
        i = left
        j = right

        while i >= 0 and j < size and s[i] == s[j]:
            i -= 1
            j += 1
        return s[i + 1:j], j - i - 1
        
# @lc code=end

回文链表

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        slow,fast,prev = head,head,None
        #找到链表的中间位置
        while fast is not None:
            slow = slow.next
            fast = fast.next.next if fast.next is not None else fast.next
        #反转后半段链表       
        while slow is not None:
            slow.next,slow,prev = prev,slow.next,slow
        #从头从未遍历链表
        while head and prev:
            if head.val != prev.val:
                return False
            head = head.next
            prev = prev.next
        return True

最长回文子序列

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        n = len(s)
        if not s:
            return 0
        #画出状态转移矩阵就可以知道下面的base 和循环的意思了。
        dp = [[0]*(n) for _ in range(n)]
        for i in range(n):
            dp[i][i] = 1
        for i in range(n-1,-1,-1):
            for j in range(i+1,n):
                if s[i] == s[j]:
                    dp[i][j] = dp[i+1][j-1]+2
                else:
                    dp[i][j] = max(dp[i+1][j],dp[i][j-1])
        return dp[0][-1]

最长回文子序列

由于是回文,所以需要用到二维dp数组,dp[i][j]表示从nums[i]到nums[j]之间的最长回文序列长度。所以若nums[i]==nums[j]则dp[i][j]==dp[i+1][j-1]+2,否则dp[i][j]==max(dp[i+1][j],dp[i][j-1]),然后还需要一个小技巧。就是画出dp矩阵后我们发现dp[i][i]==1,所以需要后序遍历或者斜着遍历。
后序:for (int i = n - 1; i >= 0; i–) 斜着:for (int l = 2; l <= n; l++) {
{for (int j = i + 1; j < n; j++)} for (int i = 0; i <= n - l; i++) {int j = l + i - 1;}

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        n = len(s)
        if not s:
            return 0
        #画出状态转移矩阵就可以知道下面的base 和循环的意思了。
        dp = [[0]*(n) for _ in range(n)]
        for i in range(n):
            dp[i][i] = 1
        for i in range(n-1,-1,-1):
            for j in range(i+1,n):
                if s[i] == s[j]:
                    dp[i][j] = dp[i+1][j-1]+2
                else:
                    dp[i][j] = max(dp[i+1][j],dp[i][j-1])
        return dp[0][-1]

你可能感兴趣的:(算法,python的使用)