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

7.29面 tiktok测开一面

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

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

递归五部曲:

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

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

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

  • "a","aa" 这一种长度小于2的肯定是的
  • "a???a" 这种只能看中间的是否是回文字符串了所以和fi+1j-1有关
  1. dp数组如何初始化 都是false fii的情况上面考虑到了
  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]));

其实只要比较dpij = Math.max(dpi + 1j, dpij - 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);
    }
}

总结

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

相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
晨米酱3 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
彧azz3 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法