LeetCode-5-最长回文子串【动态规划】

题目

第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);
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值