再也不怕回文字符串的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);
    }
}

总结

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

相关推荐
6Hzlia7 小时前
【Hot 100 刷题计划】 LeetCode 739. 每日温度 | C++ 逆序单调栈
c++·算法·leetcode
良木生香7 小时前
【C++初阶】:STL——String从入门到应用完全指南(1)
c语言·开发语言·数据结构·c++·算法
仙草不加料8 小时前
互联网大厂Java面试故事实录:三轮场景化技术提问与详细答案解析
java·spring boot·微服务·面试·aigc·电商·内容社区
XWalnut8 小时前
LeetCode刷题 day16
数据结构·算法·leetcode·链表·动态规划
落魄江湖行8 小时前
基础篇一 Java 有了 int 为什么还要 Integer?它们到底差在哪?
java·面试·八股文
星辰_mya9 小时前
OSI 七层模型之“跨国诈骗集团”深度讲解
运维·服务器·后端·面试·架构师
foundbug9999 小时前
基于混合整数规划的电池容量优化 - MATLAB实现
数据结构·算法·matlab
木斯佳10 小时前
前端八股文面经大全:字节暑期前端一面(2026-04-21)·面经深度解析
前端·面试·校招·面经·实习
我叫黑大帅10 小时前
其实跨域问题是后端来解决的? CORS
后端·面试·go