高频leetcode字符串部分:5. 最长回文子串

5. 最长回文子串

难度中等4264收藏分享切换为英文接收动态反馈
给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:
输入:s = "babad"输出:"bab"解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"输出:"bb"
示例 3:
输入:s = "a"输出:"a"
示例 4:
输入:s = "ac"输出:"a"

提示:

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

学习(代码随想录的思路

动规五部曲:

  1. 确定dp数组(dp table)以及下标的含义
    布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。
  2. 确定递推公式
  3. 在确定递推公式时,就要分析如下几种情况。
  4. 整体上是两种,就是s[i]与s[j]相等,s[i]与s[j]不相等这两种。
  5. 当s[i]与s[j]不相等,那没啥好说的了,dp[i][j]一定是false。
  6. 当s[i]与s[j]相等时,这就复杂一些了,有如下三种情况
    情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
    情况二:下标i 与 j相差为1,例如aa,也是文子串
    情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。

思路:

“aaaa”
所以一定要从下到上,从左到右遍历,这样保证dp[i + 1][j - 1]都是经过计算
”babad“
上三角与i,j的比较

代码

class Solution {
public:
    string longestPalindrome(string s) {
        char dp[1000+5][1000+5]={0};
        int i,j;
        int l,r;
        i=j=l=r=0;
        for(i=0;i<s.length();i++)
        {
            dp[i][i]=1;
        }
        i=s.length()-1;
        //所以一定要从下到上,从左到右遍历,这样保证dp[i + 1][j - 1]都是经过计算
        //上三角
        while(i>=0)
        {
            j=i;
            while(j<s.length())
            {
                // printf("%d %d\n",i,j);
                if((j-i)<=1)
                {
                    if(s[i]==s[j])
                    {
                        dp[i][j]=1;
                        // printf("--%d %d %d\n",i,j,dp[i][j]);
                        if((r-l)<(j-i))
                        {
                            l=i;
                            r=j;
                        }
                    }
                }
                else{
                    // printf("==%d %d\n",i,j);
                    if(s[i]==s[j])
                    {
                        // printf("--%d %d\n",i,j);
                        if(i+1>=s.length()||j-1<0||dp[i+1][j-1]==1)
                        {
                            dp[i][j]=1;
                            // printf("%d-%d,%d-%d\n",l,r,i,j);
                            if((r-l)<(j-i))
                            {
                                l=i;
                                r=j;
                                // printf("y\n");
                            }
                        }
                        
                    }
                }
                j++;
            }
            i--;
        }
        // for(i=0;i<s.length();i++)
        // {
        //     for(j=0;j<s.length();j++)
        //     {
        //         printf("%d",dp[i][j]);
        //     }
        //     printf("\n");
        // }
        printf("(%d-%d)\n",l,r);
        return s.substr(l, r-l+1);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值