1312. 让字符串成为回文串的最少插入次数

题目链接:

本题为经典的区间 \(dp\) 问题。

\(f[i][j]\) 表示将子串(端点为 \(i,j\))转换为回文串所需的最少插入次数。

若首尾字符相同,则只需考虑去除首尾元素的子串。
反之,若首尾元素不相同,则
① 先不看首元素,考虑 \(f[i+1][j]\),将其转换为回文串后只需在最后添加一个和首元素相同的字符即可。
② 先不看尾元素,考虑 \(f[i][j-1]\),将其转换为回文串后只需在开头添加一个和尾元素相同的字符即可。

由此可列出状态转移方程:

if (s[i] == s[j]) f[i][j] = f[i + 1][j - 1];
else f[i][j] = min(f[i + 1][j], f[i][j - 1]) + 1;

值得注意的一点是\(f[i][j]\) 中关于 \(i\) 的一维只会由 \(i+1\) 转移而来,关于 \(j\) 的一维只会由 \(j-1\) 转移而来。因此 \(i\)倒序遍历,而 \(j\)正序遍历

class Solution {
public:
    static const int N = 510;
    int f[N][N];
    int minInsertions(string s) {
        int length = s.size();
        for (int i = length - 1; i >= 0; i--) {
            for (int j = i + 1; j < length; j++) {
                if (s[i] == s[j]) f[i][j] = f[i + 1][j - 1];
                else f[i][j] = min(f[i + 1][j], f[i][j - 1]) + 1;
            }
        }
        return f[0][length - 1];
    }
};
posted @ 2024-04-08 20:22  胖柚の工作室  阅读(36)  评论(0)    收藏  举报