项目场景
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
提示:
1 <= s.length <= 1000 s 仅由数字和英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-palindromic-substring
问题描述及解决
1. 动态规划问题如何求解?
动态规划的一般形式是求最优值!
可操作性的动态规划解题步骤:
第一步:断定一个问题是不是动态规划问题?(重叠子问题、最优子结构,“最 ”
字要注意)。
当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质 。
动态规划经分解得到的子问题往往不是相互独立的
第二步:确定状态及其含义;
第三步:构造状态转移方程(根据题目给定的条件,枚举若干子状态,然后尝试用这些子状态构造出未知状态的解,就可以轻松得到状态转移方程,当然这一步离不开大量的练习)。
第四步:为状态添加备忘录或者 DP Table(根据个人喜欢,两者没有绝对的好坏之分)
2. 求指针数组的长度
指针指向的字符数组长度的获取方法,不能用sizeof,因为用sizeof(指针),得到指针长度为4,应该用strlen()函数。
strlen(s1);
返回字符串 s1 的长度。
注意添加头文件#include<string.h>
3. 可变大小的对象可能无法初始化
源代码
char * longestPalindrome(char * s){
//记录回文串的信息 (记得初始化)
int maxLength = 1; //定义一个最大长度
int begin = 0; //定义一个起始位置
int length = strlen(s);//求指针数组的长度
//用 DP Table 保存每一个子问题的解
int dp[length][length]; //初始化,置为0
//所有长度为 1 的子串都是回文串
for (int i = 0; i < length; i++)
{
dp[i][i] = 1;
}
//长度从 2 开始,枚举若干子状态,以便构造出未知状态的解
for(int len = 2; len <= length; len++)
{
//起始位置从 0 开始
for(int i = 0; i < length; i++){
///结束位置
int j = i + len - 1;
//注意结束位置越界
if (j >= length)
{
break;
}
//子串首尾字母相同的情况
if (s[i] == s[j])
{
//子串的长度为2或3,即为回文串
if (j - i < 3)
{
dp[i][j] = 1;
}
//子串的长度大于3
else
{
dp[i][j] = dp[i + 1][j - 1];
}
}
else
{
dp[i][j] = 0;
}
//记录回文串的起始位置和长度
if (dp[i][j] == 1 && len > maxLength) {
maxLength = len;
begin = i;
}
}
}
//设置结束位置
s[begin + maxLength] = '\0';
return s+begin;
}