📌  相关文章
📜  要替换的最小字符数以生成给定的字符串Palindrome(1)

📅  最后修改于: 2023-12-03 15:27:54.395000             🧑  作者: Mango

要替换的最小字符数以生成给定的字符串Palindrome

一个字符串是回文串,当且仅当该字符串从左往右读和从右往左读完全相同。现在给定一个字符串,你可以对它进行任意次以下两种操作中的一种:

  • 把字符串的某个字符修改成任意一个小写英文字母。
  • 把字符串的某个字符删除。

请你计算在最少进行多少次操作之后,能将该字符串转化为一个回文串。

解法

要让给定的字符串变成回文串,按照题目中的两种操作方式需要进行以下步骤:

  1. 从左边(或右边)开始,比较对称位置上的字符是否相等,如果相等,则不需要进行任何操作,如果不相等,则需要替换其中的一个字符。
  2. 继续往中间进行比较操作,如果某个位置上的字符需要替换,则需要累加操作次数。

那么如何确定哪些位置上的字符需要替换呢?我们可以使用动态规划算法来解决。具体地,假设给定的字符串为 $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];
}