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];
}
};

浙公网安备 33010602011771号