题解 | #字符串最小变换次数#

字符串最小变换次数

http://www.nowcoder.com/practice/2561ad26e8804cf8801926f03708ef03

本题为计算字符串的编辑距离

设两个字符串s1, s2长度分别为m, n, f(m, n)为将s1变换为s2的最小变换次数。

考虑s1的第m个字符s1[m-1],s2的第n个字符s2[n-1](下标从0开始),有两种情况:

  1. s1[m-1] == s2[n-1]
    则最小变换次数为将s1的前m-1个字符变为s2的前n-1个字符的最小变换次数
    f(m, n) = f(m-1, n-1)
  2. s1[m-1] != s2[n-1]
    根据题目的三种变换方式,将s1变为s2的最后一步可能是
  • 将s1最后一个字符删掉 => 转化为求f(m-1, n)
  • 将s2最后一个字符删掉 => 转化为求f(m, n-1)
  • 将s1最后一个字符替换为s2最后一个字符 => 转换为求f(m-1, n-1)
    结果为三者中最小值 + 1
    f(m, n) = min{ f(m-1, n), f(m, n-1), f(m-1, n-1) } + 1

综合两种情况,f(m, n) 与f(m-1, n-1)、f(m, n-1)、f(m-1,n)有关,实现的过程就是填满如下二维表格的过程,每个格子的值可能来自其上方、左边或左上方的格子。另外,为了方便编写代码,添加了第0行和第0列:
图片说明

import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args) throws Exception {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        char[] s1 = in.readLine().trim().toCharArray();
        char[] s2 = in.readLine().trim().toCharArray();
        int[][] dp = new int[s1.length+1][];
        for (int i = 0; i < dp.length; i++) {
            dp[i] = new int[s2.length+1];
        }
        // 初始化第一行和第一列
        for (int i = 0; i <= s1.length; i++) {
            dp[i][0] = i;
        }
        for (int j = 0; j <= s2.length; j++) {
            dp[0][j] = j;
        }
        // 填其余格子
        for (int i = 1; i <= s1.length; i++) {
            for (int j = 1; j <= s2.length; j++) {
                if (s1[i-1] == s2[j-1]) {
                    dp[i][j] = dp[i-1][j-1];
                } else {
                    dp[i][j] = Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1])) + 1;
                }
            }
        }
        System.out.println(dp[s1.length][s2.length]);
    }
}
全部评论

相关推荐

01-16 18:34
四川大学 Java
欢迎加入AI:没有啥稳定不稳定,一切都源于业务快速发展还是收缩。我当年一开始去的央企,业务不赚钱,也贼卷,慢慢就开始优化了。。。
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务