【经典算法题】最长回文子串

【经典算法题】最长回文子串

Leetcode 0005 最长回文子串

问题描述

在这里插入图片描述

解法一

分析

  • 考点中心扩散法

  • 我们依次枚举字符串中的每个字母s[i],然后让s[i]或者(s[i], s[i+1])为中心,向两边扩展,得到以该中心为回文串的大小,记录长度最大的回文串的起点和长度。

代码

  • C++
class Solution {
public:
    string longestPalindrome(string s) {

        int start = 0, len = 1;  // 回文串的起点和长度
        for (int i = 0; i < s.size(); i++) {
            int curL = max(expand(s, i, i), expand(s, i, i + 1));
            if (curL > len) {
                len = curL;
                start = i - (curL - 1) / 2;
            }
        }
        return s.substr(start, len);
    }

    int expand(string s, int i, int j) {

        while (i >= 0 && j < s.size()) {
            if (s[i] != s[j]) break;
            i--, j++;
        }
        return j - i - 1;
    }
};
  • Java
class Solution {
    public String longestPalindrome(String s) {

        char[] cs = s.toCharArray();

        int start = 0, len = 1;  // 回文串的起点和长度
        for (int i = 0; i < cs.length; i++) {
            int curL = Math.max(expand(cs, i, i), expand(cs, i, i + 1));
            if (curL > len) {
                len = curL;
                start = i - (curL - 1) / 2;
            }
        }
        return s.substring(start, start + len);
    }

    private int expand(char[] s, int i, int j) {

        while (i >= 0 && j < s.length) {
            if (s[i] != s[j]) break;
            i--; j++;
        }
        return j - i - 1;
    }
}
  • Python
class Solution:
    def longestPalindrome(self, s: str) -> str:
        start = 0
        length = 1
        for i in range(len(s)):
            curL = max(self.expand(s, i, i), self.expand(s, i, i + 1))
            if curL > length:
                length = curL
                start = i - (curL - 1) // 2
        return s[start: start + length]

    def expand(self, s, i, j):
        while i >= 0 and j < len(s):
            if s[i] != s[j]:
                break
            i -= 1
            j += 1
        return j - i - 1

时空复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)n为字符串长度。

  • 空间复杂度: O ( 1 ) O(1) O(1)

解法二

分析

  • 考点马拉车算法。考点详解网址:马拉车算法
  • 原理讲解请参考上述网址,这里不再重复。
  • 本题需要求解这个最长回文子串,如果在新串中p[i]取得了最大值,则最长回文子串的长度为len=p[i]-1
  • 最长回文子串在原串中的起始位置为i / 2 - 1 - (len - 1) / 2

代码

class Solution {
public:
    string longestPalindrome(string s) {
        string t = "$#";
        for (auto c : s) t += c, t += '#';
        t += '^';

        // manacher
        int n = t.size();
        vector<int> p(n + 10, 0);
        int mr = 0, mid;
        for (int i = 1; i < n; i++) {
            if (i < mr) p[i] = min(p[mid * 2 - i], mr - i);
            else p[i] = 1;

            while (t[i - p[i]] == t[i + p[i]]) p[i]++;

            if (i + p[i] > mr) {
                mr = i + p[i];
                mid = i;
            }
        }

        // 求解最长回文子串起始位置和长度
        int len = 0, start = 0;
        for (int i = 0; i < n; i++) {
            p[i]--;
            if (p[i] > len) {
                len = p[i];
                start = i / 2 - 1 - (l - 1) / 2;
            }
        }

        return s.substr(start, len);
    }
};

时空复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)n为字符串长度。

  • 空间复杂度: O ( n ) O(n) O(n)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中的代码是一个使用暴力解法求解最长回文子串的示例。该代码通过截取字符串的所有子串,并判断这些子串中哪些是回文的,最后返回回文子串中最长的。这个算法的时间复杂度较高。引用中的代码是使用边界扩散法求解最长回文子串的示例。该算法通过从中心向两边扩展的方式,依次判断是否为回文子串,并记录最长回文子串的起止位置。这个算法的时间复杂度较低。引用中的代码也是使用边界扩散法求解最长回文子串的示例。该代码通过遍历字符串,以每个字符为中心,向两边扩展,判断回文子串的长度,并记录最长回文子串的起止位置。最后返回最长回文子串。这个算法的时间复杂度较低。根据引用和引用中的代码,可以整合出一个完整的Python代码来求解最长回文子串: class Solution: def isPalindrome(self, s, start, end): while start < end: if s[start != s[end]: return False start += 1 end -= 1 return True def longestPalindrome(self, s): max_len = 0 start = 0 end = 0 for i in range(len(s)): j = i + 1 while j < len(s): if self.isPalindrome(s, i, j): if (j - i + 1) > max_len: max_len = j - i + 1 start = i end = j + 1 j += 1 return s[start:end] s = "ac" S = Solution() result = S.longestPalindrome(s) print(result) 这段代码使用边界扩散法来求解最长回文子串。首先定义了一个isPalindrome函数来判断一个子串是否为回文子串。然后,在longestPalindrome函数中,通过两层循环遍历字符串,以每个字符为中心,向两边扩展,判断回文子串的长度,并记录最长回文子串的起止位置。最后返回最长回文子串。对于输入字符串"ac",输出结果为"a"。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Python最长回文子串](https://blog.csdn.net/weixin_42698464/article/details/121389797)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [5.最长回文子串 && 647.回文子串 (python)](https://blog.csdn.net/cqjnovo/article/details/124318575)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Python:实现最长回文子串算法(附完整源码)](https://blog.csdn.net/it_xiangqiang/article/details/128828664)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值