📅  最后修改于: 2023-12-03 15:27:54.395000             🧑  作者: Mango
一个字符串是回文串,当且仅当该字符串从左往右读和从右往左读完全相同。现在给定一个字符串,你可以对它进行任意次以下两种操作中的一种:
请你计算在最少进行多少次操作之后,能将该字符串转化为一个回文串。
要让给定的字符串变成回文串,按照题目中的两种操作方式需要进行以下步骤:
那么如何确定哪些位置上的字符需要替换呢?我们可以使用动态规划算法来解决。具体地,假设给定的字符串为 $s$,它的长度为 $n$,$dp[i][j]$ 表示将 $s[i:j+1]$ 子串变成回文串需要的最小操作次数,则状态转移方程为:
$$ dp[i][j] = \begin{cases} dp[i+1][j-1] & {s_i=s_j} \ min{dp[i+1][j], dp[i][j-1]} + 1 & {s_i \neq s_j} \end{cases} $$
其中,当 $s_i=s_j$ 时,说明当前位置不需要进行任何操作;当 $s_i \neq s_j$ 时,说明当前位置需要替换字符,并将其操作次数加上 1。
最终,整个字符串变成回文串所需的最小操作次数就是 $dp[0][n-1]$。时间复杂度为 $O(n^2)$。
Python 代码实现:
def minOpsToPalindrome(s):
n = len(s)
dp = [[0] * n for _ in range(n)]
for i in range(n-2, -1, -1):
for j in range(i+1, n):
if s[i] == s[j]:
dp[i][j] = dp[i+1][j-1]
else:
dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1
return dp[0][n-1]
Java 代码实现:
public int minOpsToPalindrome(String s) {
int n = s.length();
int[][] dp = new int[n][n];
for (int i = n-2; i >= 0; i--) {
for (int j = i+1; j < n; j++) {
if (s.charAt(i) == s.charAt(j)) {
dp[i][j] = dp[i+1][j-1];
} else {
dp[i][j] = Math.min(dp[i+1][j], dp[i][j-1]) + 1;
}
}
}
return dp[0][n-1];
}