zoukankan      html  css  js  c++  java
  • LeetCode 5. 最长回文子串

    5. 最长回文子串

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

    示例 1:

    输入: "babad"
    输出: "bab"
    注意: "aba" 也是一个有效答案。
    示例 2:

    输入: "cbbd"
    输出: "bb"

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/longest-palindromic-substring
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    题解

      最常用的方法应该有三个,暴力解,动态规划和中心扩展,

      动态规划

      当字符串长度为1的时候,必然是个回文串,那长度为3的情况下呢,就需要s[i] == s[i + 3]的情况下才能形成回文

      或者说长度为2时,需要s[i] == s[i + 1]形成回文

      so,可以得出个结论,子串从 i 到 j 如果想是个回文,需满足两个条件:

      1. 子串[i + 1, j - 1]是个回文

      2.字符s[i] == s[j]

      SO, 可以得出状态方程

      dp[i, j] = dp[i + 1, j - 1] && s[i] == s[j]

      用个dp[s.len][s.len]来表示子串从i到j是否是回文串,未必最长回文串;  

      在dp总,dp[i][i]比如是个回文,因为长度只有1(i - i + 1);

      所以可以将dp[i][i]直接先赋值为true,并且作为最初始的判断条件

            for (int i = 0; i < len; i++) {
                dp[i][i] = true;
            }

      进而考虑边界条件dp[i + 1][j - 1]的边界问题:

      如果从s[i + 1, j - 1]的长度小于2,既为0 或者1的时候:

      如果是0,那必然是回文; 如果是1,则只需要判断s[i] s[j]是否相等即可,可以把这两个判定归类在s[i]==s[j]的情况下,dp[i][j]为回文

      代码如下:

    string longestPalindrome(string s) {
            // 特判
            int len = s.length();
            if (len < 2) {
                return s;
            }
    
            int maxLen = 1;
            int begin = 0;
    
            // dp[i][j] 表示 s[i, j] 是否是回文串
            vector<vector<int>> dp(len, vector<int>(len));
    
            for (int i = 0; i < len; i++) {
                dp[i][i] = true;
            }
            for (int j = 1; j < len; j++) {
                for (int i = 0; i < j; i++) {
                    printf("str = %s 
    ", s.substr(i, j - i + 1).c_str());
    
                    if (s[i] != s[j]) {
                        dp[i][j] = false;
                    }
                    else {
                        if (j - i < 3) { //(j-1) - (i+1) + 1 < 2 从i到j的内部小于等于1
                            dp[i][j] = true;
                        }
                        else {
                            dp[i][j] = dp[i + 1][j - 1];
                        }
                    }
    
                    // 只要 dp[i][j] == true 成立,就表示子串 s[i..j] 是回文,此时记录回文长度和起始位置
                    if (dp[i][j] && j - i + 1 > maxLen) {
                        maxLen = j - i + 1;
                        begin = i;
                    }
                }
            }
            return s.substr(begin, begin + maxLen);
    }

      中心扩展

       核心思想是对每个字符以及两个字符中间作为中心点,向两边扩展,判定是否是回文,得出最长

      为什么是每个字符以及两个字符中间作为中心点呢,因为字符长度可以是基数或者偶数

    class Solution {
    public:
        pair<int, int> expandAroundCenter(const string& s, int left, int right) {
            while (left >= 0 && right < s.size() && 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.size(); ++i) {
                auto [left1, right1] = expandAroundCenter(s, i, i);
                auto [left2, right2] = expandAroundCenter(s, i, i + 1);
                if (right1 - left1 > end - start) {
                    start = left1;
                    end = right1;
                }
                if (right2 - left2 > end - start) {
                    start = left2;
                    end = right2;
                }
            }
            return s.substr(start, end - start + 1);
        }
    };

      另:马拉车算法

      太复杂了,等我看明白先!!!

      

  • 相关阅读:
    AWS IoT Greengrass:配置安装 AWS CLI
    AWS IoT Greengrass:如何使用 AWS 管理控制台配置本地资源访问
    AWS IoT Greengrass 入门-模块6: 访问其他 AWS 服务
    AWS IoT Greengrass 入门-模块5:与设备影子交互
    AWS IoT Greengrass 入门-模块4:在 AWS IoT Greengrass 组中与设备交互
    AWS IoT Greengrass 入门-模块3(第 2 部分):AWS IoT Greengrass 上的 Lambda 函数
    Nginx 启动报错 (nginx: error while loading shared libraries: XXX: cannot open shared object file: No such file or directory ) 的解决办法
    自己制作一个简单的操作系统二[CherryOS]
    Linux-误删apt-get以及把aptitude换回
    完美解决phpstudy安装后mysql无法启动(无需删除原数据库,无需更改任何配置,无需更改端口)直接共存
  • 原文地址:https://www.cnblogs.com/gongkiro/p/13637223.html
Copyright © 2011-2022 走看看