5-Longest Palindromic Substring-最长回文串

问题描述

链接: https://leetcode.com/problems/longest-palindromic-substring/description/

Given a string s, return the longest  palindromic substring in s

解释: 给定一个字符串,求其最长的回文串
回文串:一个字符串,如果从左往右读和从左往右读 读出来的序列是一样的,称之为回文串。比如 aba, 从左往后和从右往左都是 aba

基本思想

构建数组dp, 大小为s的长度。则 \(dp[i]\): 以i为中心的回文串的最大长度。而后依次一s[i]为中心,计算回文串。
如上过程存在如下问题:

  • s的长度为奇数时候可以,为偶数的时候不行,不如bb,此时回文串没有中心。所以要先将 s变换为奇数。变换方式如下:在s的元素之间增加"#"形成新的字符串str。

如上思路还存在如下问题:

  1. 如何区分'#d#' 和 ‘d#d’ ?这两个回文串 明显后者才是正确的,但是其长度是一样的
    1. 增加 一个变量,记录 一个回文串的#的数目

最差时间复杂度O(n^2)

代码

C++

string longestPalindrome(string s) {
         int size = s.size();
         if (size<=1) return s;
         string str; // 将str长度变为奇数
        for(int i=0;i<(size-1);++i) {
            str += s[i];
            str += '#';
        }
        str += s[size-1];
         vector<int> dp(str.size(),1); // 以str[i]为中心的最长回文串的长度
         int res = 1;
         int index = 0;
         int r_count = 0;
         for(int i=1; i<str.size();++i) {
            int x = i-1;
            int y = i + 1;
            int count=0;
            if (str[i] == '#') ++count;
            while(x>=0 && y<str.size() && str[x]==str[y]) {
                dp[i]=dp[i]+2;
                if(str[x] == '#') 
                  count = count+2;
                --x;
                ++y;
            }
            if ((res-r_count)<(dp[i]-count)) {
                res = dp[i];
                index = i;
                r_count = count;
            }
         }
         string s1;
         int i = index - res/2; 
         while(i<=(index+res/2)) {
            if (str[i]!='#') {
                s1 += str[i];
            }
            ++i;
         }
        return s1;
    }

python

 def longestPalindrome(self, s: str) -> str:
        n = len(s)
        if n<=1: return s
        str=''
        for i,ele in enumerate(s):
            str += ele
            if  i != (n-1):
                str += '#'
        dp = [1] * len(str)
        maxLength = 1
        index = 0
        count = 0
        for i in range(1,len(str)):
            x = i-1
            y = i+1
            rn = 0
            if str[i] == '#':
                rn = 1
            while x >= 0 and y < len(str) and str[x] == str[y]:
                if str[x] == '#':
                    rn = rn+ 2
                x = x-1
                y = y +1
                dp[i] = dp[i] + 2
            if (maxLength-count) < (dp[i] - rn):
                maxLength = dp[i]
                index = i
                count = rn
        s1 = ''
        i = index - maxLength//2
        while i<=(index+ maxLength//2):
            if str[i] != '#':
                s1 += str[i]
            i=i+1
        return s1 
posted @ 2024-05-20 22:23  金字塔下的蜗牛  阅读(1)  评论(0编辑  收藏  举报