代码随想录算法训练营第六十天_第九章_动态规划 | 647. 回文子串、516.最长回文子序列、动态规划总结篇
创始人
2024-05-23 14:03:22
0

LeetCode 647. 回文子串

        给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

视频讲解https://www.bilibili.com/video/BV17G4y1y7z9/?spm_id_from=333.788&vd_source=f98f2942b3c4cafea8907a325fc56a48文章讲解https://programmercarl.com/0647.%E5%9B%9E%E6%96%87%E5%AD%90%E4%B8%B2.html

⭐如果s[i + 1, j - 1]是回文子串 且 s[i] == s[j] 👉s[i, j]是回文子串

  • 思路:
    • 思路一,动态规划:
      • dp数组含义:bool类型 dp[i][j] 表示 子串[i, j]是否回文
      • 递推公式:只用维护 i <= j 的 dp[i][j],考虑以下情况
        • 情况一:i == j,例如"a",true
        • 情况二:i + 1 == j,例如"aa",true
        • 情况三:i + 1 < j,看dp[i + 1][j - 1](此时dp[i + 1][j - 1]才有意义)
      • 初始化:全false
      • 遍历顺序:从下到上/从左到右
    • 思路二,双指针:
      • 遍历s,取中心点用于向两边对称位置扩展
        • 以 i 为中心(奇数)
        • 以 i 和 i + 1 为中心(偶数)
      • 从中心向两边比较,统计回文子串的数目
  • 代码:
// 思路一,动态规划:
class Solution {
public:int countSubstrings(string s) {vector> dp(s.size(), vector(s.size(), false));int result = 0;for (int i = s.size() - 1; i >= 0; i--) {  // 注意遍历顺序for (int j = i; j < s.size(); j++) {if (s[i] == s[j]) {if (j - i <= 1) { // 情况一 和 情况二result++;dp[i][j] = true;} else if (dp[i + 1][j - 1]) { // 情况三result++;dp[i][j] = true;}}}}return result;}
};// 简洁版:
class Solution {
public:int countSubstrings(string s) {vector> dp(s.size(), vector(s.size(), false));int result = 0;for (int i = s.size() - 1; i >= 0; i--) {for (int j = i; j < s.size(); j++) {if (s[i] == s[j] && (j - i <= 1 || dp[i + 1][j - 1])) {result++;dp[i][j] = true;}}}return result;}
};
// 时间复杂度:O(n^2)
// 空间复杂度:O(n^2)
// 思路二,双指针:
class Solution {
public:int countSubstrings(string s) {int result = 0;for (int i = 0; i < s.size(); i++) {result += extend(s, i, i, s.size()); // 以i为中心result += extend(s, i, i + 1, s.size()); // 以i和i+1为中心}return result;}int extend(const string& s, int i, int j, int n) {int res = 0;while (i >= 0 && j < n && s[i] == s[j]) {i--;j++;res++;}return res;}
};
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)

LeetCode 516.最长回文子序列

        给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。

视频讲解https://www.bilibili.com/video/BV1d8411K7W6/?spm_id_from=333.788&vd_source=f98f2942b3c4cafea8907a325fc56a48文章讲解https://programmercarl.com/0516.%E6%9C%80%E9%95%BF%E5%9B%9E%E6%96%87%E5%AD%90%E5%BA%8F%E5%88%97.html

  • 思路:
    • dp数组含义:dp[i][j] 表示 子串[i, j]的最长回文子序列的长度
    • 递推公式:
      • s[i] 与 s[j] 相同👉dp[i][j] = dp[i + 1][j - 1] + 2;
      • s[i] 与 s[j] 不同👉dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);

    • 初始化:dp[i][i] = 1;其余全0
    • 遍历顺序:从下到上,从左到右
    • 最终结果:dp[0][s.size() - 1]; 
  • 代码:
class Solution {
public:int longestPalindromeSubseq(string s) {vector> dp(s.size(), vector(s.size(), 0));for (int i = 0; i < s.size(); i++) dp[i][i] = 1;for (int i = s.size() - 1; i >= 0; i--) {for (int j = i + 1; j < s.size(); j++) {if (s[i] == s[j]) {dp[i][j] = dp[i + 1][j - 1] + 2;} else {dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);}}}return dp[0][s.size() - 1];}
};

⭐拓展:LeetCode 5.最长回文子串

  • dp数组含义:dp[i][j] 表示 子串[i, j]的最长回文子串的长度
  • 递推公式:
    • s[i] 与 s[j] 相同 且 [i + 1, j - 1]是回文子串👉dp[i][j] = dp[i + 1][j - 1] + 2;
      • 即 dp[i + 1][j - 1] == j - (i + 1)
      • 记录最长回文子串[start, end]
        • 每遇到一个回文子串[i, j]比较长度:j + 1 - i vs end + 1 - start
        • 若 >,则更新start、end
    • else👉dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
  • 初始化:dp[i][i] = 1;其余全0
  • 遍历顺序:从下到上,从左到右
  • 最终结果:dp[0][s.size() - 1]👉字符串s的最长回文子串的长度
    • 题目要求返回最长回文子串

动态规划总结篇

动规五部曲:

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

动态规划基础: 

理论基础、509.斐波那契数、70.爬楼梯、746.使用最小花费爬楼梯:Day 38

62.不同路径Ⅰ、63.不同路径Ⅱ:Day 39

343.整数拆分、96.不同的二叉搜索树:Day 41

背包问题系列

01背包理论基础二维、一维、416:Day 42

1049、494、474:Day 43

完全背包理论基础、518、377:Day 44

70(进阶)、322、279:Day 45

139、多重背包、背包问题总结:Day 50

打家劫舍系列:Day 51

打家劫舍Ⅰ:线

打家劫舍Ⅱ:环

打家劫舍Ⅲ:树形dp

股票系列:Day 52、Day 53、Day 55

子序列系列:

300、674、718:Day 56

1143、1035、53:Day 57

392、115:Day 58

583、72:Day 59

647、516:Day 60

相关内容

热门资讯

黄山云海导游词 黄山云海导游词范文(精选10篇)  作为一名专门引导游客、助人为乐的导游,总归要编写导游词,导游词可...
宜春明月山导游词 宜春明月山导游词  宜春是个出美景的好地方。小编下面为大家收集整理了宜春明月山导游词,欢迎阅读!  ...
河南导游词 河南导游词  作为一位出色的导游人员,常常要写一份好的导游词,导游词具有极强的实用性,涉及的知识十分...
民居导游词六百字 民居,也是特色的景点之一。以下是PINCAI小编整理的关于导游词的相关内容,欢迎阅读和参考!民居导游...
英文导游词欢迎词 篇一:英文导游欢迎词范文Ladies and gentlemen:Welcome to ______...
介绍青岛的导游词 介绍青岛的导游词  作为一名专门引导游客、助人为乐的导游,往往需要进行导游词编写工作,导游词的主要特...
介绍山西普救寺导游词 介绍山西普救寺导游词  作为一无名无私奉献的导游,时常要开展导游词准备工作,导游词是导游员在游览时为...
孔府导游词 >孔府导游词颜宇欣 各位游客: 大家好!欢迎大家来到孔府游玩,孔府导游词。我是今天的导游颜宇欣,大家...
乔家大院简介导游词 乔家大院简介导游词  导游词是导游人员引导游客观光游览时的讲解词,是导游员同游客交流思想,向游客传播...
乐山大佛导游词 乐山大佛导游词500字五篇  作为一位尽职的导游,有必要进行细致的导游词准备工作,导游词是导游员同游...
湖北武当山紫霄宫导游词 湖北武当山紫霄宫导游词各位朋友们:  紫霄到了,你们看前面半天云里山峰是否像一面展开的旗帜,这就是展...
明十三陵概况及神道导游词 明十三陵概况及神道导游词  明十三陵位于北京市昌平区北部天寿山下,因明代迁都北京后,有十三位皇帝埋葬...
九华山导游词作文400字 九华山导游词作文400字  以下是九华山的导游词作文400字范文,希望对大家有帮助!  篇一:九华山...
绍兴兰亭风景区导游词 绍兴兰亭风景区导游词  作为一名乐于助人的导游,常常需要准备导游词,导游词具有极强的实用性,涉及的知...
天下第一宫—黄帝... 天下第一宫—黄帝宫游览区导游词  作为一位兢兢业业的旅游从业人员,总不可避免地需要编写导游词,导游词...
导游词之大九湖 导游词之大九湖  我们今天游览的是被称其为湖北的“呼伦贝尔”的大九湖风景区,大九湖并非湖,而是一片沼...
上饶三清山导游词 上饶三清山导游词(通用9篇)  作为一名乐于助人的导游,通常需要用到导游词来辅助讲解,导游词具有形象...
洪崖丹井导游词 洪崖丹井导游词3篇  作为一名尽职尽责的导游,编写导游词是必不可少的,导游词具有注重口语化、精简凝练...
沈阳新乐遗址导游词 关于沈阳新乐遗址导游词范文  新乐文化遗址位于沈阳市皇姑区黄河北大街北运河北岸黄土高台之上,1977...
西山导游词 西山导游词(15篇)  作为一名专门为游客提供优质服务的导游人员,编写导游词是必不可少的,导游词具有...