美文网首页
LintCode 200. 最长回文子串

LintCode 200. 最长回文子串

作者: CW不要无聊的风格 | 来源:发表于2020-05-26 10:18 被阅读0次

题目描述

给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。


测试样例

输入:"abcdzdcab"

输出:"cdzdc"

输入:"aba"

输出:"aba"


解题思路与方法

1、暴力搜索

i). 将输入字符串s逆序反转的到s1,比如abcde则变为edcba;

ii). 依次遍历输入字符串s的每一个字符的位置,将其作为起始位i。每次固定i,然后从i开始依次遍历至字符串s的最后一个位置,将其作为终止位j。在这期间每遍历一个j便判断从i到j的子串是否出现在s1中,从而确定从i到j的子串是否回文;

iii). 若s中从i到j的子串是回文,则比较这个回文子串与之前获得的最长回文子串的长度;若当前回文子串的长度大,则更新获得的最长回文子串长度,同时记录下最长回文子串的起止位置i、j;

iv). 重复ii)和iii)直至将i遍历完s的所有字符位置

2、动态规划

i). 建立一个2维数组,用于记录从位置i到位置j是否是回文子串(O(n^2)的空间复杂度);

ii). 依次遍历输入字符串s的每个位置,将其作为终止位right;然后从right开始向左边遍历每个位置,将其作为起始位置left,直至s的第一个字符位置;

iii). 当left和right相邻或者两者之间的子串是回文,并且当前left和right位置的字符相等,那么更新2维数组,记录下从位置left到位置right是回文子串。同时,比较该回文子串与之前获得的最长回文子串的长度,若当前较大,则更新最长回文子串长度,同时记录下最长回文子串的起始位置分别为left和right;

iv). 重复ii)和iii),直至right遍历完s的所有字符位置

3、有点暴力的中线扩充

i). 依次遍历输入字符串s的每个位置i,从i出发向左右两边扩充,获得left和right两个位置;

ii). 同时,从i和i右边的一个位置j出发,分别向左和向右(i向左、j向右)扩充,获得left和right两个位置;

iii). 在i)和ii)中,分别进入循环,对于每个left-right对,当它们都位于s中的有效位置且当前位于left和right的字符相等时,left和right就分别向左和向右移动,直至left和right有其一走到了s的有效位置之外或者left与right位置上的字符不相等,则跳出循环;

iv). 跳出循环后,比较left和right之间的回文子串长度与之前获得的最长回文子串长度,若当前较大,则更新这个长度,同时记录下这个最长回文子串;

v). 重复i)、ii)、iii)直至遍历完s中的所有位置


代码

1、暴力搜索

class Solution:

    """

    @param s: input string

    @return: the longest palindromic substring

    """

    def longestPalindrome(self, s):

        # write your code here

        if not s:

            return ""

        if len(s) == 1:

            return s

        # 记录最长回文子串的长度

        longest_len = 0

        # 最长回文子串的起止,

        # 其中right是excluded,即[left, right)

        left = right = 0

        # 将字符串反转

        inverted_s = s[::-1]

        for i in range(len(s)):

            # 注意j要到len(s),这样才可能取到最后一个字符

            for j in range(i + 1, len(s) + 1):

                if s[i:j] in inverted_s and len(s[i:j]) > longest_len:

                    left = i

                    right = j

                    longest_len = len(s[i:j])

        return s[left:right]

2、动态规划

class Solution:

    """

    @param s: input string

    @return: the longest palindromic substring

    """

    def longestPalindrome(self, s):

        # write your code here

        if not s:

            return ""

        if len(s) == 1:

            return s

        # 最长回文子串的头尾字符

        # 其中tail是included

        head = tail = 0

        # 记录最长回文子串的长度

        longest_len = 0

        # 记录从第i个字符到第j个字符是否是回文

        is_palindrome = [[False] * len(s) for _ in range(len(s))]

        for right in range(len(s)):

            for left in range(right, -1, -1):

                if (right - left < 2 or is_palindrome[left + 1][right - 1]) \

                    and s[left] == s[right]:

                    is_palindrome[left][right] = True

                    cur_len = right - left + 1

                    if cur_len > longest_len:

                        head = left

                        tail = right

                        longest_len = cur_len

        return s[head:tail + 1]

3、中线扩充

class Solution:

    """

    @param s: input string

    @return: the longest palindromic substring

    """

    longest_palindrome = ''

    def longestPalindrome(self, s):

        # write your code here

        if not s:

            return ""

        if len(s) == 1:

            return s

        for start in range(len(s)):

            # 从start位置向两边扩展判断是否最长回文子串

            self.find_longest_palindrome(s, start, start)

            # 从start和start+1位置向两边扩展判断是否最长回文子串

            self.find_longest_palindrome(s, start, start + 1)

        return self.longest_palindrome

    def find_longest_palindrome(self, s, left, right):

        while left >= 0 and right < len(s) and s[left] == s[right]:

            left -= 1

            right += 1

        # 注意跳出循环后left是在回文子串的第一个字符的左边一个位置

        # right是在回文子串最后一个字符的右边一个位置

        if right - left - 1 > len(self.longest_palindrome):

            self.longest_palindrome = s[left + 1:right]

相关文章

  • LintCode 200. 最长回文子串

    题目描述 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。...

  • Lintcode-最长回文子串

    问题描述: 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串...

  • 最长回文子串

    最长回文子串——Manacher 算法 1. 问题定义 最长回文字符串问题:给定一个字符串,求它的最长回文子串长度...

  • 字符串算法

    最长公共前缀 最长回文串 最长回文子序列 最长公共子串 反转单词顺序列 反转字符串 字符串转数字 IP-int互转

  • 打卡-最长回文子串

    最长回文子串(中等)

  • 最长回文子序列

    该问题区别于最长回文子串,子串必须是连续的,而子序列则可以跳跃,例如AABCAA的最长回文子串为AA,但是它的最长...

  • Manacher算法

    最长回文子串问题# 给定一个字符串,找出最长的回文子串,如"waabwswbfd",则最长子串为bwsb. 中心试...

  • 最长回文子串问题—Manacher算法

    最长回文串问题是一个经典的算法题。 0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度。如果...

  • LeetCode 第647题:回文子串

    1、前言 2、思路 此题与最长回文子串很像,只不过那个是求最长的回文子串,而这个是求回文子串的数目。但是他们的解法...

  • C语言实现求最长回文子串

    最长回文子串的概念 回文串是指正序和反序都一样的字符串,例如:Str1 = "AbbA",则Str1的最长回文子串...

网友评论

      本文标题:LintCode 200. 最长回文子串

      本文链接:https://www.haomeiwen.com/subject/encmahtx.html