Leetcode 5.最长回文子串:解题思路

Leetcode 5.最长回文子串:解题思路

题目链接:

https://leetcode-cn.com/problems/longest-palindromic-substring/

题目描述

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

思路

对于这个问题,很明显是存在两个需要解决的问题,一个是判断子串是不是回文,另一个是找到是回文的子串中最长的那个。对于第一个问题,采用头尾双指针的方法就可以解决,时间复杂度是O(n);对于第二个问题,需要遍历所有子串,所以时间复杂度是O(n2)。如果分别对这两个问题进行处理的话,那么时间复杂度至少是O(n3)。再仔细思考一下,可以发现这两个问题其实存在共同的步骤,因此可以对这两个问题进行合并。当一个子串去除头尾两个字符为回文子串时,如果这两个字符相同,那么该字串必定为回文子串;反之,肯定不是回文子串。所以可以有两种思路在遍历所有子串的同时找到最长回文子串,一种就是把每个字符作为中心向两端同时扩散的方法遍历,另一种是构建n2矩阵采用动态规划的方法遍历。不过在遍历的时候需要注意回文子串的对称中心可能不在字符上而是在两个字符之间,可以通过分类讨论或者在每个字符间插入特殊符号的方法来解决。

代码

这里给出第一种方法的代码

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        if not s:
            return s
        #插入特殊符号*
        new_s = '*'.join(list(s))
        max_length, max_str = 1, s[0]
        #开始遍历子串,并假定每个字符为子串中心进行遍历
        for index, i  in enumerate(new_s):
            gap = min(index+1, len(new_s)-index)
            for j in range(1, gap):
                if new_s[index-j] == '*':
                    continue
                if new_s[index-j] == new_s[index+j]:
                    if 2*j+1 > max_length:
                        max_length = 2*j + 1
                        max_str = new_s[index-j:index+j+1]
                else:
                    break
        return ''.join([i for i in max_str if i != '*'])

DLC

其实这个问题还有更快的解决方法,那就是著名的马拉车算法—Manacher 算法。该算法的时间复杂度只有O(n),不过算法比较复杂,短时间内很难想出来,所以这里不再赘述,有兴趣可以自行百度或者谷歌搜索[doge]。

你可能感兴趣的:(leetcode)