再也不怕回文字符串的dp了

7.29面 tiktok测开一面

采用例题+自己理解的方式解决这个系列的问题

第一题:回文字符串的个数

递归五部曲:

  1. 确定dp含义,dp[i][j]是i到j是否是回文字符串
  2. 确定递推公式,

s.charAt(i)!=s.charAt(j)不用看了

s.charAt(i)==s.charAt(j):

  • "a","aa" 这一种长度小于2的肯定是的
  • "a???a" 这种只能看中间的是否是回文字符串了所以和f[i+1][j-1]有关
  1. dp数组如何初始化 都是false f[i][i]的情况上面考虑到了
  2. 递归顺序,根据地推公式,需要从左下往右上推,所以横排倒序,竖排正序

5.举例推导dp数组 6->2 9->4 10->5

java 复制代码
class Solution {
    public int countSubstrings(String s) {
        int len = s.length();
        int ans = 0;

        boolean[][] f = new boolean[len][len];

        for(int i=len-1;i>=0;i--){
            for(int j = i;j<len;j++){
                if(s.charAt(i)==s.charAt(j)){
                    if(j-i<=1){
                        f[i][j] = true;
                        ans++;
                    }else if(f[i+1][j-1]){
                        ans++;
                        f[i][j] = true;
                    }
                }
            }
        }
        return ans;
    }
}

第二题:最长回文子序列

这题相较于上面一题的不同就是递推公式d:

java 复制代码
if (s.charAt(i) == s.charAt(j)) { 
    dp[i][j] = dp[i + 1][j - 1] + 2; 
} else { 
    dp[i][j] = Math.max(dp[i + 1][j], Math.max(dp[i][j], dp[i][j - 1]));
}

这里是序列,所以 asca这个的长度也是2

如果是ascb 则需要看asc和scb的长度谁长

这里我看代码随想录还比较了

ini 复制代码
 dp[i][j] = Math.max(dp[i + 1][j], Math.max(dp[i][j], dp[i][j - 1]));

其实只要比较dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); 因为上面我们说过了遍历的顺序,这题也一样 只会遍历一遍

java 复制代码
public class Solution {
    public int longestPalindromeSubseq(String s) {
        int len = s.length();
        int[][] dp = new int[len + 1][len + 1];
        for (int i = len - 1; i >= 0; i--) { // 从后往前遍历 保证情况不漏
            dp[i][i] = 1; // 初始化
            for (int j = i + 1; j < len; j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                } else {
                    dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[0][len - 1];
    }
}

第三题:最长回文子串

再回头看这题 难点就是,如何确定dp数组的含义了,这题虽然是求最长的,但是还是用了boolean数组,额外维护一个最长的区间就行了。

java 复制代码
class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();

        boolean[][] f = new boolean[len][len];
        int maxLen = 0, l=0, r=0;

        for(int i=len-1;i>=0;i--){
            for(int j=i;j<len;j++){
                if(s.charAt(i)==s.charAt(j)){
                    if (j - i <= 1) { // 情况一 和 情况二
                        f[i][j] = true;
                    } else if (f[i + 1][j - 1]) { // 情况三
                        f[i][j] = true;
                    }
                }
                if(f[i][j] && j-i+1>maxLen){
                    maxLen = j-i+1;
                    l = i;
                    r = j;
                }
            }
        }
        return s.substring(l,r+1);
    }
}

总结

代码还是自己敲一遍熟悉。。。。面试手撕高压环境没有熟练度和思维根本不可能做出来

相关推荐
野犬寒鸦18 分钟前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
霖霖总总20 分钟前
[小技巧66]当自增主键耗尽:MySQL 主键溢出问题深度解析与雪花算法替代方案
mysql·算法
rainbow688927 分钟前
深入解析C++STL:map与set底层奥秘
java·数据结构·算法
wangjialelele1 小时前
平衡二叉搜索树:AVL树和红黑树
java·c语言·开发语言·数据结构·c++·算法·深度优先
驱动探索者1 小时前
linux mailbox 学习
linux·学习·算法
ringking1231 小时前
autoware-1:安装环境cuda/cudnn/tensorRT库函数的判断
人工智能·算法·机器学习
小迷糊的学习记录2 小时前
0.1 + 0.2 不等于 0.3
前端·javascript·面试
程序员敲代码吗2 小时前
面试中sessionStorage问题引发深度探讨
面试·职场和发展
大闲在人2 小时前
8. 供应链与制造过程术语:产能
算法·制造·供应链管理·智能制造·工业工程
一只小小的芙厨2 小时前
寒假集训笔记·以点为对象的树形DP
c++·算法