编辑距离 动态规划与状态压缩

编辑距离是比较经典的动态规划问题 指的是将一个字符创S1通过增删改的方式转为S2,比如将

rad转化为apple 则最少需要5步 即删除R,跳过A,将D转为P,增加P,增加L,增加E

动态规划解法如下

public class TEST编辑距离 {
    //对一个字符串进行3种操作 插入 删除 替换 ,给定2个字符串 计算将s1转换为S2最少需要几次操作
    //这里是将S1 变成S2
     static int mindistance(String s1,String s2){
         int m=s1.length(),n=s2.length();
         //dp的定义 S1[0...i] 和S2[0...j]的最短编辑距离为dp[i][j]
         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];
                 }else {
                     dp[i][j]=min(dp[i-1][j]+1,//插入 在I这个位置插入一个和J相同的元素
                             dp[i][j-1]+1,//删除 在I这个位置删除 使得保持一致
                             dp[i-1][j-1]+1);//修改 使得i和j 的元素相同
                 }
             }
         }
         return dp[m][n];
     }

     
     static int min(int a ,int b,int c){
         return Math.min(a,Math.min(b,c));
     }

    public static void main(String[] args) {
        String s1="rad";
        String s2="apple";
        int i = mindistance(s1, s2);
        System.out.println(i);
    }


}

动态规划如上 可以看到dp[I]][J]的状态只与dp[i-1][j-1],dp[i-1][j],dp[i][j-1]y有关,因此可以使用状态压缩进一步降低空间复杂度

状态压缩如下:

public class TEST编辑距离 {
    //对一个字符串进行3种操作 插入 删除 替换 ,给定2个字符串 计算将s1转换为S2最少需要几次操作
    //这里是将S1 变成S2
   

     //状态压缩
    static int mindistance2(String s1,String s2){
        int m=s1.length();
        int n=s2.length();
        if(m==0)
            return n;
        if(n==0)
            return m;
        int[] dp=new int[n+1];
        for(int i=0;i<=n;i++)
            dp[i]=i;
        for(int i=1;i<=m;i++){
            int pre=1;
            for(int j=1;j<=n;j++){
                if(j==1)
                    dp[j-1]=i;
                int temp=pre;
                pre=dp[j];
                //int temp=dp[j];
                if(s1.charAt(i-1)==s2.charAt(j-1)) {
                    dp[j]=temp;
                }
                else {
                    dp[j]=Math.min(Math.min(temp,dp[j]),dp[j-1])+1;
                }
            }
        }
        return dp[n];
    }

    

    public static void main(String[] args) {
        String s1="rad";
        String s2="apple";
        int i = mindistance2(s1, s2);
        System.out.println(i);
    }


}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值