代码随想录算法训练营第六十天_第九章_动态规划 | 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

相关内容

热门资讯

滑雪英语作文【精简6篇】 滑雪英语作文 篇一:滑雪初体验I still remember the first time I w...
我们的长江英语作文【精彩3篇... 我们的长江英语作文 篇一长江是中国最长的河流,也是世界第三长的河流。作为中国的母亲河,长江对于中国人...
高考英语满分作文 2014高考英语满分作文  【作文题目】  最近,你校同学正在参加某英文报组织的一场讨论。讨论的主题...
我的暑假英语作文(最新3篇) 我的暑假英语作文 篇一Summer Vacation MemoriesSummer vacation...
我喜爱夏天英语作文(精彩3篇... 我喜爱夏天英语作文 篇一Summer is my favorite season of the ye...
大学与教育话题英语范文(精选... 大学与教育话题英语范文 篇一The Role of Universities in Educatio...
维持健康的英语范文初中(优选... 维持健康的英语范文初中 篇一Title: The Importance of Exercise fo...
我的家庭英语作文(最新6篇) 我的家庭英语作文 篇一My FamilyMy family is the most importan...
愉快的一天英语作文(优秀6篇... 愉快的一天英语作文 篇一A Wonderful DayToday was a wonderful d...
我的妹妹英语作文(优质6篇) 我的妹妹英语作文 篇一My Younger SisterI have a younger siste...
申请书必用的英文单词(精选3... 申请书必用的英文单词 篇一In the process of writing an applicat...
保持健康的英语作文(通用3篇... 保持健康的英语作文 篇一Title: The Importance of Exercise for ...
我的朋友英语作文(优质6篇) 我的朋友英语作文 篇一My Friend LucyI would like to talk abou...
元旦英语作文(优秀6篇) 元旦英语作文 篇一:新年愿望New Year's WishesAs the New Year app...
我的周末计划英语作文【通用6... 我的周末计划英语作文 篇一My Weekend PlanThis weekend, I have a...
性格英语作文(推荐6篇) 性格英语作文 篇一The Importance of Positive Character Trai...
初一英语作文我的假期(实用3... 初一英语作文我的假期 篇一My Summer Vacation During my summer...
欺负同学处理通告范文英语(优... 欺负同学处理通告范文英语 篇一Title: Announcement on Dealing with...
学习的英语作文【最新5篇】 学习的英语作文 篇一The Importance of Continuous Learning in...
我的妈妈英语作文【优选6篇】 我的妈妈英语作文 篇一My Amazing MomMy mom is the most incred...