栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

LeetCode 5. 最长回文子串

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LeetCode 5. 最长回文子串

文章目录
  • 1.动态规划
  • 2.中心扩展法
  • 3.中心扩展法的优化

题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/

1.动态规划

思路如下:

假设字符串 s = “babad”,它的长度为 n。

dp 是大小为 n ∗ n n*n n∗n 的二维数组, d p [ i ] [ j ] dp[i][j] dp[i][j] 表示 s [ i , j ] s[i,j] s[i,j] 是否为回文串,存储 true/false。

如果 s [ i , j ] s[i,j] s[i,j] 的长度小于等于 2 2 2 时

  • 如果 s [ i ] s[i] s[i] 等于 s [ j ] s[j] s[j],那么 s [ i , j ] s[i,j] s[i,j] 是回文串,所以 d p [ i ] [ j ] = ( s [ i ] = = s [ j ] ) dp[i][j] = (s[i] == s[j]) dp[i][j]=(s[i]==s[j])

如果 s [ i , j ] s[i,j] s[i,j] 的长度大于 2 2 2 时

  • 如果 s [ i + 1 , j − 1 ] s[i+1,j-1] s[i+1,j−1] 是回文串,并且 s [ i ] s[i] s[i] 等于 s [ j ] s[j] s[j],那么 s [ i , j ] s[i,j] s[i,j] 是回文串
    所以 d p [ i ] [ j ] = d p [ i + 1 , j − 1 ]   & &   ( s [ i ] = = s [ j ] ) dp[i][j] = dp[i+1,j-1] && (s[i] == s[j]) dp[i][j]=dp[i+1,j−1] && (s[i]==s[j])

时间复杂度为 O ( n 2 ) O(n^2) O(n2)

空间复杂度为 O ( n 2 ) O(n^2) O(n2)

C++代码如下:

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        if (n == 0 || n == 1)   return s;

        vector> dp(n, vector(n));
        int maxLen = 1; // 记录最长回文子串的长度
        int beginIdx = 0; // 记录最长回文子串的开始索引

        for (int i = n - 1; i >= 0; i--) {
            for (int j = i; j < n; j++) {
                int len = j - i + 1;
                dp[i][j] = (s[i] == s[j]) && (len <= 2 || dp[i + 1][j - 1]);
                if (dp[i][j] && len > maxLen) {
                    maxLen = len;
                    beginIdx = i;
                }
            }
        }

        return s.substr(beginIdx, maxLen);
    }
};
2.中心扩展法

思路如下:

枚举回文子串的中点,从中间向两边扩展,直到左右两边的字符不相等为止,记录最长的回文子串即可。

要注意区分长度为奇数的回文串和长度为偶数的回文串。

假设字符串 s = “abbaba” 的长度为 n n n,那么一共有 n + ( n − 1 ) = 2 n − 1 n+(n-1)=2n-1 n+(n−1)=2n−1个扩展中心。

时间复杂度为 O ( n 2 ) O(n^2) O(n2)

空间复杂度为 O ( 1 ) O(1) O(1)

C++代码如下:

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        if (n == 0 || n == 1)   return s;

        int maxLen = 1; // 记录最长回文子串的长度
        int beginIdx = 0; // 记录最长回文子串的开始索引

        for (int i = 0; i < n; i++) {
        	// 以字符s[i]为中心,向左、向右扩展
            int l = i - 1, r = i + 1;
            while (l >= 0 && r < n && s[l] == s[r]) {
                l--;
                r++;
            }
            if (r - l - 1 > maxLen) {
                maxLen = r - l - 1;
                beginIdx = l + 1;
            }
            
            // 以字符s[i]右边的间隙为中心,向左、向右扩展
            l = i, r = i + 1;
            while (l >= 0 && r < n && s[l] == s[r]) {
                l--;
                r++;
            }
            if (r - l - 1 > maxLen) {
                maxLen = r - l - 1;
                beginIdx = l + 1;
            }
        }
        
        return s.substr(beginIdx, maxLen);
    }
};
3.中心扩展法的优化

思路如下:

将连续的相同字符组成的子串作为扩展中心,所以字符串 s = “babbbabaa” 的扩展中心有 “b”、“a”、“bbb”、“a”、“b”、“aa”。

步骤:

  • 找到右边第一个不等于 s [ i ] s[i] s[i] 的字符记为位置 r r r, s [ i ] s[i] s[i] 左边的位置记为 l l l
  • r r r 作为下一次的 i i i
  • 由 l l l 开始向左、 r r r 开始向右扩展,找到最长的回文子串

时间复杂度为 O ( n 2 ) O(n^2) O(n2)

空间复杂度为 O ( 1 ) O(1) O(1)

C++代码如下:

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        if (n == 0 || n == 1)   return s;

        int maxLen = 1; // 记录最长回文子串的长度
        int beginIdx = 0; // 记录最长回文子串的开始索引

        int i = 0;
        while (i < n) {
        	// s[i]左边的位置记为l
            int l = i - 1;

            // 找到右边第一个不等于s[i]的位置r
            int r = i + 1;
            while (r < n && s[r] == s[i]) {
                r++;
            }

            // r会成为新的i
            i = r;

            // 从l向左扩展,从r向右扩展
            while (l >= 0 && r < n && s[l] == s[r]) {
                l--;
                r++;
            }

            // 扩展结束后,s[l + 1, r - 1]就是刚才找到的最大回文子串
            if (r - l - 1 > maxLen) {
                maxLen = r - l - 1;
                beginIdx = l + 1;
            }
        }

        return s.substr(beginIdx, maxLen);
    }
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/872993.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号