LeetCode72-edit distance:动态规划

 

/*给你两个单词word1和word2,请你计算出将word1换成word2所使用的最小操作数。
你可以对一个单词进行如下三种操作:
1.插入一个字符
2.删除一个字符
3.替换一个字符

示例1:
输入:word1=“horse”,word2=“ros”
输出:3
解释:
horse->rorse(将‘h’替换为‘r’)
rorse->rose(删除‘r’)
rose->ros(‘e’)

式例2:
输入:word1=“intention”,word2=“execution”
输出:5
解释:
intention->inention(删除‘t’)
inention->enention(将‘i’替换为‘e’)
enention->exention(将'n'替换为'x')
exention->exection(将‘n’替换为‘c’)
exction->execution(插入‘u’)
*/

/*
这是动态规划的典型题目:通过求最小步长,可以通过最优子结构n-1来推导n的情况
编辑距离,是一个典型的动态规划问题。

状态转移方程:
dp二维数组,用来保存A,即第0...i个字符变化到B第0...j个字符的最小步长
记dp[i][j]为字符串A的前i个字符到字符串B的前j个字符的编辑距离,如果A和B为空串,那么i或者j为0,
因此i的区间为[0,lenA],j的区间为[0,lenB].接下来,我们推导动态规划方程。
(1)如果A[i]等于B[j],那么此时便是躺赢的模式,即有:
    dp[i][j]=dp[i-1][j-1]
(2)如果A[i]不等于B[j],则可以进行三种操作(增删改),使得A[0...i]>B[0...j]字符串,如下:
   a.删除一个字符: dp[i][j]=dp[i-1][j]+1;
   b.增加一个字符: dp[i][j]=dp[i][j]+1;
   c.改变一个字符: dp[i][j]=dp[i-1][j-1]+1;
   
   显然得到动态规划方程为:
   dp[i][j]=1+min{dp[i-1][j],dp[i][j-1],dp[i-1][j-1]}
*/

 

Go语言实现

package main

import (
	"fmt"
)


func MinDistanc(A string,B string)int {
	lenA:=len(A)
	lenB:=len(B)

	//初始化二维slice
	dp:=make([][]int,lenA+1)
	for i:=0;i<lenA+1;i++{
		dp[i]=make([]int,lenB+1)
	}

	for i:=0;i<lenA+1;i++{
		dp[i][0]=i
	}

	for j:=0;j<lenB+1;j++{
		dp[0][j]=j
	}

	for i:=1;i<lenA+1;i++{
		for j:=1;j<lenB+1;j++{
			if A[i-1]==B[j-1]{
				dp[i][j]=dp[i-1][j-1]
			}else{
				dp[i][j]=1+min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])
			}
		}
	}
	return dp[lenA][lenB]
}

func min(x,y,z int)int{
	m:=x
	if x>y{
		m=y
	}
	if m>z{
		m=z
	}
	return m
}

func main(){
	fmt.Println("编辑距离:动态规划")
	fmt.Println("最小操作数为:",MinDistanc("chen","zh"))
}

C++语言实现 

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;
class Solution{
 public:
    int minDistanc(string A,string B){
        int lenA=A.length();
        int lenB=B.length();
        vector<vector<int>> dp(lenA+1,vector<int>(lenB+1,0));

        for(int i=1;i<lenA+1;i++)
            dp[i][0]=i;
        for(int j=1;j<lenB+1;j++)
            dp[0][j]=j;
        
        for(int i=1;i<lenA+1;i++){
            for(int j=1;j<lenB+1;j++){
                if(A[i-1]==B[j-1])
                    dp[i][j]=dp[i-1][j-1];
                else 
                    dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;
            }
        }
        return dp[lenA][lenB];
    }
};

int main(int argc,char* argv[]){
    Solution temp;
    cout<<temp.minDistanc("chen","zhu")<<endl;
    return 0;
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的追梦人

您的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值