letcode 动态规划 —— 5. 最长回文子串

题目

给你一个字符串 s,找到 s 中最长的回文子串。
https://leetcode.cn/problems/longest-palindromic-substring/
 
 

这个解答方法怎么想到的?

其实官方的解答已经说的很好了,但并没有说明是怎么想到的,我在这里想谈谈自己的理解。

动态规划的本质就是状态转换方程,即我们只要找到不同状态之间的关系,就能够破题。那么我们需要关心的就是如何找到这样一个状态转换方程,我认为找到主体的关键属性就是答案

对于这道题,主体就是"回文子串",它有两个特征:
1 字符串
2 回文

其中字符串的关键属性就是长度,而回文本身就是关键属性

随着长度的变化,字符串也在变化,我们要做的就是找到长度的变化与回文这一特征的联系

到了这一步,可以自己举一些例子,例子就是基于字符串长度的变化:

ababa->bab
aa->caac

可以看到,对于一个回文串来说,不论是去掉两端的字母,还是在两端加上相同的字母,得到的结果依旧还是回文串。而这就是我们建立状态转换方程的依据

假设s代表字符串,i代表子串的开始位置,j代表子串的结束位置,dp[i][j]表示从i到j的字符串是否为回文串,那么:

if(s[i]==s[j]){
	dp[i][j]=dp[i+1][j-1];
}

翻译过来就是,如果i,j位置的字母相同,那么i到j这一子串的状态(是否回文)与去掉头尾后的i+1到j-1的子串状态相同

到此,我们解体的主体思路就成功诞生了!
 
 

题解

class Solution {
public:
    string longestPalindrome(string s) {
        int len=s.length();
        int maxlen=1,begin=0;
        if(len<2){
            return s;
        }
        int dp[len][len];
        for(int i=0;i<len;i++){
            dp[i][i] = 1;
        }
        for(int L=2;L<=len;L++){
            for(int i=0;i<len;i++){
                int j=L+i-1;  // j-i+1=L
                if(j>=len){ // 这步一定要有,防止j出界 
				    break;
			    }
                if(s[i]!=s[j]){
                    dp[i][j]=0;
                }
                else{
                    if(j-i+1<4){ // len = 1 or 2 or 3
                        dp[i][j]=1;
                    }
                    else{
                        dp[i][j]=dp[i+1][j-1];
                    }	
                }
                
                if(dp[i][j]&&j-i+1>maxlen){ // 注意判断dp[i][j]是否为1 
                    begin=i;
                    maxlen=j-i+1;
                }
            }
        }
        return s.substr(begin,maxlen);
    }
};

 
 

提交结果

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值