[动态规划]最长回文子串-对于动态转移循环顺序的思考
标题
给你一个字符串 s,找到 s 中最长的回文子串。
样例
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解答思路
本题使用dp的思想
- 为了得到回文子串的开始和结尾所以要得到两个值,所以dp数组选择二维数组,dp[i][j]表示字符串i位置到j位置的子串是否为回文串
- 那么我们就研究动态转移方程,思考dp[i][j]从dp[i + 1][j - 1]来(可以想到,"babab"由"aba"来,由于添加的'b'和'b'相等,所以"babab"继承了"aba"的回文性质),那么dp[i][j]是否为回文串和字符串i和j位置的字符是否相等息息相关,结果是由dp[i + 1][j - 1]决定
- 所以得到转移条件和方程 如果 j - i >= 3 && 字符串s[i] == s[j] 那么 dp[i][j] = dp[i + 1][j - 1]
易错点
平常的动态规划都是对dp数组直接按行循环,但是这道题不行,因为我们发现dp[i][j] = dp[i + 1][j - 1]这个状态意味着每个位置都由他的左下角决定,如果按行来,那么左下角还没有状态导致错误
所以我们要按列来进行状态转移
代码
func longestPalindrome(s string) string {
dp := make([][]bool,len(s))
for i := range dp {
dp[i] = make([]bool,len(s))
dp[i][i] = true
}
be,end := 0,0
maxlen := -1
for j := 0;j < len(s);j++ {
for i := 0; i < j;i++ {
if s[i] != s[j] {
dp[i][j] = false
}else {
if j - i >= 3 {
dp[i][j] = dp[i + 1][j - 1]
}else{
dp[i][j] = true
}
}
if dp[i][j] == true && j - i > maxlen {
maxlen = j - i
be,end = i,j
}
}
}
return string(s[be:end + 1])
}
分类:
leetcode题解
, 算法思想
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)