《LeetCode之每日一题》:65.最长回文子串

Posted 是七喜呀!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:65.最长回文子串相关的知识,希望对你有一定的参考价值。

最长回文子串


题目链接: 最长回文子串

有关题目

给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:

输入:s = "cbbd"
输出:"bb"
示例 3:

输入:s = "a"
输出:"a"
示例 4:

输入:s = "ac"
输出:"a"
提示:

1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成

题解

法一:动态规划

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        //特判
        if (n < 2)
            return s;
        
        int maxLen = 1;
        int begin = 0;

        // dp[i][j] 表示 s[i..j] 是否是回文串
        vector<vector<int>> dp(n, vector<int>(n));
        // 初始化:所有长度为 1 的子串都是回文串
        for (int i = 0; i < n; i++)
        {
            dp[i][i] = true;
        }

        // 递推开始
        // 先枚举子串长度
        for (int L = 2; L <= n; L++)
        {
            // 枚举左边界,左边界的上限设置可以宽松一些
            for (int i = 0; i < n; i++)
            {
                // 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
                int j = L + i - 1;
                // 如果右边界越界,就可以退出当前循环
                if (j >= n)
                    break;
                if (s[i] != s[j])
                    dp[i][j] = false;
                else
                {
                    if (j - i < 3)
                    dp[i][j] = true;
                    else 
                    dp[i][j] = dp[i + 1][j  - 1];
                }

                // 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
                if (dp[i][j] && j - i + 1 > maxLen)
                    {
                        maxLen = j - i + 1;
                        begin = i;
                    }
            }
        }
        return s.substr(begin,maxLen);
    }
};

在这里插入图片描述
法二:中心扩展算法

class Solution {
public:

    pair<int,int> expandAroundCentre(const string& s, int left, int right)
    {
        while(left >= 0 && right < s.length() && s[left] == s[right])
        {
            left--;
            right++;
        }
        return {left + 1, right - 1};
    }
    string longestPalindrome(string s) {
        int start = 0, end = 0;
        for (int i = 0; i < s.length(); i++)
        {
            auto[left1,right1] = expandAroundCentre(s,i,i);
            auto[left2,right2] = expandAroundCentre(s,i,i + 1);
            if (right1 - left1 > end - start)//end - start的值随着回文子串的长度而增加
                {
                    start = left1;
                    end = right1;
                }
            if (right2 - left2 > end - start)
                {
                    start = left2;
                    end = right2;
                }
        }
        return s.substr(start,end - start + 1);
    }
};

在这里插入图片描述

以上是关于《LeetCode之每日一题》:65.最长回文子串的主要内容,如果未能解决你的问题,请参考以下文章

《LeetCode之每日一题》:246.分割回文串

leetcode每日一题:409. 最长回文串

每日算法/刷穿 LeetCode5. 最长回文子串(中等)

每日一道leetcode:5. 最长回文子串

小Y学算法⚡️每日LeetCode打卡⚡️——5.最长回文子串

最长回文子串