算法打卡:第九章 动态规划part13

打印 上一主题 下一主题

主题 510|帖子 510|积分 1530

今日劳绩:回文子串,最长回文子序列

1. 回文子串

标题链接:647. - 力扣(LeetCode)
思路:
(1)dp数组的界说不再是标题的要求,而是二维的,下标 i 和 j 表示字符串对应下标的子串是不是回文串。再使用变量记录回文子串的个数
(2)初始化全为0
(3)如果当前两个字符相等,判定长度是否为0或1,满足要求则都是回文子串;如果长度大于1,那么下标向中间聚拢,如果仍然是回文子串,记录个数。
(4)遍历次序:依据递推公式,需要下标向中间聚拢也就是左下角的值推出当前值,所以需要从上到下从左到右遍历。
方法:
  1. class Solution {
  2.     public int countSubstrings(String s) {
  3.         int len=s.length();
  4.         int result=0;
  5.         // 字符串中从 i 到 j 的子串是不是回文串
  6.         boolean[][] dp=new boolean[len][len];
  7.         // 初始化
  8.         for (int i=0;i<len;i++){
  9.             for (int j=0;j<len;j++){
  10.                 dp[i][j]=false;
  11.             }
  12.         }
  13.         // 从底向上,从左到右
  14.         for (int i=len-1;i>=0;i--){
  15.             for (int j=i;j<len;j++){
  16.                 if (s.charAt(i)==s.charAt(j)){
  17.                     if (j-i<=1){
  18.                         dp[i][j]=true;
  19.                         result++;
  20.                     }else {
  21.                         dp[i][j]=dp[i+1][j-1];  // 向中间靠拢
  22.                         if (dp[i][j]==true){
  23.                             result++;
  24.                         }
  25.                     }
  26.                 }
  27.             }
  28.         }
  29.         return result;
  30.     }
  31. }
复制代码
2. 最长回文子序列

标题链接:516. - 力扣(LeetCode)
思路:
(1)dp数组表示 i 和 j 下标范围内的最长回文子序列长度
(2)初始化:递推公式不包罗长度为1的回文子串,所以二维数组的对角线元素全为1
(3)递推公式:如果 i 和 j 下标上的字符相等,那么回文子序列的长度在内层子串的基础上加2;如果不相等,则取分别加上左边的字符和右边的字符中的最大值。
(4)遍历次序:从递推公式可以看出来,当前位置依靠于左,左下,下的元素值,所以是从下到上,从左到右遍历。
方法:
  1. class Solution {
  2.     public int longestPalindromeSubseq(String s) {
  3.         int len=s.length();
  4.         // 设置为len+1,初始化较为简单
  5.         int[][] dp=new int[len+1][len+1];
  6.         for (int i=len-1;i>=0;i--){
  7.             dp[i][i]=1;
  8.             for (int j=i+1;j<len;j++){
  9.                 if (s.charAt(i)==s.charAt(j)){
  10.                     dp[i][j]=dp[i+1][j-1]+2;
  11.                 }else {
  12.                     dp[i][j]=Math.max(dp[i+1][j],dp[i][j-1]);
  13.                 }
  14.             }
  15.         }
  16.         return dp[0][len-1];
  17.     }
  18. }
复制代码
总结:
(1)子序列和子串的区别在于,子序列可以删除元素,如果可以删除的环境不止一个就需要取此中的最大值。
(2)如果不能确定遍历次序,可以根据递推公式,分析dp数组中当前位置的值由哪些方向的值推导出来。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

花瓣小跑

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表