Dynamic Programming学习笔记 (18) - 回文子串最少删除数

341 阅读1分钟

回文子串最少删除数是另一个回文子串相关的DP应用,题面为

给定一个长度为N的字符串 s ,删除最少数量的字符使之成为一个回文子串。

实例:

s = "aebcbda"
答案是2,删除'e''d'这两个字符后变成回文子串"abcba"

解题思路:

沿用回文子串解题方法,我们定义一个DP表达式F(i, j),i和j是字串数组下标,F(i, j)返回的是对于从i到j的子串而言,使之成为回文子串所需删除的最少字符数。F(i, j)的返回值有两种可能性。

  1. 如果s[i]与s[j]相同,那么F(i, j)的返回值就是F(i+1, j - 1)
  2. 如果s[i]与s[j]不同,那么F(i, j)的返回值就是F(i+1, j)和F(i, j - 1)中的较小值。

从以上表达式出发,我们使用二维DP数组,以及双重循环,外层从大到小,内层从小到大,依次计算,最后DP[1][N]中的数值就是问题的答案。

Java代码:

class Solution {
    public int palindromeDeletions(String s) {

        char[] chars = s.toCharArray();
        int N = chars.length;

        if (N <= 1) {
            return 0;
        }

        int[][] dp = new int[N + 1][N + 1];

        for (int i = N; i >= 1; i --) {
            for (int j = i + 1; j <= N; j ++) {
                int count = 0;

                if (chars[i - 1] == chars[j - 1]) {
                    if (j - i > 2) {
                        count = dp[i + 1][j - 1];
                    }
                } else {
                    count = Math.min(1 + dp[i + 1][j], 1 + dp[i][j - 1]);
                }

                dp[i][j] = count;
            }
        }
        return dp[1][N];
    }
}