题目
第5题 最长回文子串
https://leetcode-cn.com/problems/longest-palindromic-substring/
题解
基础知识点
vector的初始化
参考链接
(1): vector ilist4(7);
默认值初始化,ilist4中将包含7个元素,每个元素进行缺省的值初始化,对于int,也就是被赋值为0,因此ilist4被初始化为包含7个0。当程序运行初期元素大致数量可预知,而元素的值需要动态获取的时候,可采用这种初始化方式。
(2):vector ilist5(7,3);
指定值初始化,ilist5被初始化为包含7个值为3的int
2维vector的初始化
方法一:
先创建要一个二维的,再遍历初始化里面的大小
//得到一个5行3列的数组
//由vector实现的二维数组,可以通过resize()的形式改变行、列值
int i,j;
vector<vector<int>> array(5);
for (i = 0; i < array.size(); i++)
array[i].resize(3);
方法2:
先创建里面小的,再用这个小的初始化大的
vector<bool> tmpVec(sSize, false);
vector<vector<bool>> store(sSize, tmpVec);
DP动态规划讲解
这个dp的讲解非常优秀了!
「暴力算法」是基础,「动态规划」必须掌握,「中心扩散」方法要会写;
「Manacher 算法」仅用于扩宽视野,绝大多数的算法面试中,面试官都不会要求写这个方法(除非面试者是竞赛选手)。
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
状态转移矩阵:
dp[i][j]=True if s[i]=s[j] and (i+1>=j−1 or dp[i+1][j−1])
dp[i][j]=False if s[i] != s[j] and (i+1>=j−1 or dp[i+1][j−1])
附代码
这个点很多,已经在代码中注释了~
2维数组的压缩也值得好好看看,后续再看~
class Solution {
public:
string longestPalindrome(string s) {
int len = s.size();
if (len < 2) {
return s;
}
int max_length = 1;
int begin = 0;
// vector 初始化方法1:
// vector<bool> tmp_vec(len, false);
// vector<vector<bool>> dp(len, tmp_vec);
// vector 初始化方法2:
// vector<vector<bool>> dp(len);
// for (int i = 0; i < len; i++)
// dp[i].resize(len);
// 优化点1: 非常关键:之前一直超时,而且发现最开始初始化为false实际上没有生效(因为发现不能跳过下面的对不相等的元素设为false,按理应该是可以的)
// 不要使用bool值,vector中存bool值不是一个真正的bool值组成的vector,采用的是一个代理类,get,set操作有一定成本,直接使用int代替bool就行
vector<int> tmp_vec(len, 0);
vector<vector<int>> dp(len, tmp_vec);
// 优化点2:跳过对角线的判断,因为对角线上的值不会被其它状态值所参考。
// for (int i = 0; i < len; i++) {
// dp[i][i] = true;
// }
for (int j = 1; j < len; j++) { // 为什么要从1开始?因为串的长度超过1了,j是有节点
for (int i = 0; i < j; i++) { // 为啥i要在内层, i<j保证在矩阵右上角,因为i是左节点,j是右节点
// for (int i = j - 1; i >= 0; i--) { // 也可以倒着填写
if (s[i] != s[j]) {
// 优化点3:不用对dp数组填充false,为了提升速度
// dp[i][j] = 0;
// 优化点4:重要,这里能够知道 dp[i][j] = false 后面的逻辑就没有必要走了
continue;
} else if (j - i < 3) {
dp[i][j] = 1;
} else {
dp[i][j] = dp[i + 1][j - 1];
}
if (dp[i][j] && j - i + 1 > max_length) {
max_length = j - i + 1;
begin = i;
}
}
}
return s.substr(begin, max_length);
}
};