题意整理。

  • 输入两个字符串,求它们之间的编辑距离。
  • Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

方法一(动态规划)

1.解题思路

  • 状态定义:dp[i][j]dp[i][j]表示字符串A长度为i,字符串B长度为j时,对应的编辑距离。
  • 状态初始化:其中一个字符串为空时,编辑距离为另一个字符串的长度。即dp[i][0]=i,dp[0][j]=jdp[i][0]=i,dp[0][j]=j
  • 状态转移:如果当前字符相等,直接等于前一个位置的情况。即dp[i][j]=dp[i1][j1]dp[i][j]=dp[i-1][j-1]。如果不相等,要么s1字符串插入s2中j位置对应字符即dp[i][j]=dp[i1][j]+1dp[i][j]=dp[i-1][j]+1,要么s2字符串插入s1中i位置对应字符即dp[i][j]=dp[i][j1]+1dp[i][j]=dp[i][j-1]+1,要么s1字符串i位置字符被s2字符串j位置字符替换,即dp[i][j]=dp[i1][j1]+1dp[i][j]=dp[i-1][j-1]+1

图解展示: alt

2.代码实现

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            //输入字符串A
            String s1=sc.next();
            //输入字符串B
            String s2=sc.next();
            //计算字符串A和字符串B的距离
            System.out.println(distance(s1,s2));
        }
    }
    private static int distance(String s1,String s2){
        int m=s1.length();
        int n=s2.length();
        //定义dp数组
        int[][] dp=new int[m+1][n+1];
        //状态初始化
        for(int i=1;i<=m;i++){
            dp[i][0]=i;
        }
        for(int j=1;j<=n;j++){
            dp[0][j]=j;
        }
        //状态转移
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                //如果相等,直接等于前一个位置的情况
                if(s1.charAt(i-1)==s2.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1];
                }
                /*
                如果不相等,要么B字符串插入A中i位置对应字符即dp[i][j]=dp[i-1][j]+1
                要么A字符串插入B中j位置对应字符即dp[i][j]=dp[i][j-1]+1,要么s1字符串
                i位置字符被s2字符串j位置字符替换,即dp[i][j]=dp[i-1][j-1]+1
                */
                else{
                    dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
                }
            }
        }
        return dp[m][n];
    }
}

3.复杂度分析

  • 时间复杂度:两层循环,最多执行mnm*n次,所以时间复杂度为O(mn)O(m*n)
  • 空间复杂度:需要额外大小为mnm*n的空间,所以空间复杂度为O(mn)O(m*n)

方法二(利用io操作)

1.解题思路

与方法一的思路基本一致,不过使用io操作来处理输入数据。

2.代码实现

import java.io.*;

public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s1,s2;
        //输入字符串A和B
        while((s1=br.readLine())!=null){
            s2=br.readLine();
            //计算字符串A和字符串B的距离
            System.out.println(distance(s1,s2));
        }
    }
    private static int distance(String s1,String s2){
        int m=s1.length();
        int n=s2.length();
        //定义dp数组
        int[][] dp=new int[m+1][n+1];
        //状态初始化
        for(int i=1;i<=m;i++){
            dp[i][0]=i;
        }
        for(int j=1;j<=n;j++){
            dp[0][j]=j;
        }
        //状态转移
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                //如果相等,直接等于前一个位置的情况
                if(s1.charAt(i-1)==s2.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1];
                }
                /*
                如果不相等,要么B字符串插入A中i位置对应字符即dp[i][j]=dp[i-1][j]+1
                要么A字符串插入B中j位置对应字符即dp[i][j]=dp[i][j-1]+1,要么s1字符串
                i位置字符被s2字符串j位置字符替换,即dp[i][j]=dp[i-1][j-1]+1
                */
                else{
                    dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
                }
            }
        }
        return dp[m][n];
    }
}

3.复杂度分析

  • 时间复杂度:两层循环,最多执行mnm*n次,所以时间复杂度为O(mn)O(m*n)
  • 空间复杂度:需要额外大小为mnm*n的空间,所以空间复杂度为O(mn)O(m*n)