[leetcode] 72. 编辑距离(二维动态规划)

再次验证leetcode的评判机有问题啊!同样的代码,第一次提交超时,第二次提交就通过了!
此题用动态规划解决。
这题一开始还真难到我了,琢磨半天没有思路。于是乎去了网上喵了下题解看到了动态规划4个字就赶紧回来了。
脑海中浮现了两个问题:
为什么能用动态规划呢?用动态规划怎么解?
先描述状态吧:
f[i][j]表示word1中的[0,i] 与 word2中[0,j]的最少操作数。
实际上这时候就能看出来了,当一个状态计算完成时,即一个状态的操作方案(决策)确定时,不影响后面状态的最优决策。即满足动态规划要求的无后效性,否则不能用动规来解决啦,因为要涉及到回溯修改前面的决策。也就是满足两个条件:1. 重叠子问题 2.最优子结构
动态规划原理
虽然已经用动态规划方法解决了上面两个问题,但是大家可能还跟我一样并不知道什么时候要用到动态规划。总结一下上面的斐波拉契数列和钢条切割问题,发现两个问题都涉及到了重叠子问题,和最优子结构。
①最优子结构
用动态规划求解最优化问题的第一步就是刻画最优解的结构,如果一个问题的解结构包含其子问题的最优解,就称此问题具有最优子结构性质。因此,某个问题是否适合应用动态规划算法,它是否具有最优子结构性质是一个很好的线索。使用动态规划算法时,用子问题的最优解来构造原问题的最优解。因此必须考查最优解中用到的所有子问题。
②重叠子问题
在斐波拉契数列和钢条切割结构图中,可以看到大量的重叠子问题,比如说在求fib(6)的时候,fib(2)被调用了5次,在求cut(4)的时候cut(0)被调用了4次。如果使用递归算法的时候会反复的求解相同的子问题,不停的调用函数,而不是生成新的子问题。如果递归算法反复求解相同的子问题,就称为具有重叠子问题(overlapping subproblems)性质。在动态规划算法中使用数组来保存子问题的解,这样子问题多次求解的时候可以直接查表不用调用函数递归。
显然,状态转移方程也就出来了:
f[i][j] 的计算分为两种情况:
- 当word1[i] == word2[j] 说明此时不需要任何操作,f[i][j] = f[i-1][j-1]
- else f[i][j] = min(f[i-1][j-1] , f[i-1][j] , f[i][j-1] ) + 1 , 此时,f[i][j] 可由之前已经确定的三个状态而来(因为有三种操作),如果是word1替换操作,则之前的状态为f[i-1][j-1];word1删除操作,则之前的状态为: f[i-1][j],此时就是删除word[i];word1插入操作,则之前的状态为:f[i][j-1],此时实际上就是在word[i]后面插入word2[j]
那初始条件呢?当一方为空时,最少操作数就是另一个word的size了
for (int i = 0; i <= m; i++) {
f[i][0] = i;
}
for (int j = 0; j <= n; j++) {
f[0][j] = j;
}
1A代码
class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length();
int n = word2.length();
if (m == 0) {
return n;
}
if (n == 0) {
return m;
}
int[][] f = new int[m + 1][n + 1];
for (int i = 0; i <= m; i++) {
f[i][0] = i;
}
for (int j = 0; j <= n; j++) {
f[0][j] = j;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
f[i][j] = f[i - 1][j - 1];
} else {
f[i][j] = Collections.min(Arrays.asList(f[i - 1][j - 1], f[i - 1][j], f[i][j - 1])) + 1;
}
}
}
return f[m][n];
}
}
[leetcode] 72. 编辑距离(二维动态规划)的更多相关文章
- 动态规划小结 - 二维动态规划 - 时间复杂度 O(n*n)的棋盘型,题 [LeetCode] Minimum Path Sum,Unique Paths II,Edit Distance
引言 二维动态规划中最常见的是棋盘型二维动态规划. 即 func(i, j) 往往只和 func(i-1, j-1), func(i-1, j) 以及 func(i, j-1) 有关 这种情况下,时间 ...
- 二维动态规划——Interleaving String
97. Interleaving String Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2 ...
- 543A - Writing Code(二维动态规划)
题意:现在要写m行代码,总共有n个文件,现在给出第i个文件每行会出现v[i]个bug,问你在bug少于b的条件下有多少种安排 分析:定义dp[i][j][k],i个文件,用了j行代码,有k个bug 状 ...
- LeetCode:搜索二维矩阵【74】
LeetCode:搜索二维矩阵[74] 题目描述 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. 每行的第一个整数大于前一行的 ...
- LeetCode 74. 搜索二维矩阵(Search a 2D Matrix)
74. 搜索二维矩阵 74. Search a 2D Matrix 题目描述 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. ...
- LeetCode 240. 搜索二维矩阵 II(Search a 2D Matrix II) 37
240. 搜索二维矩阵 II 240. Search a 2D Matrix II 题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性 ...
- 第30章 LeetCode 72 编辑距离
每日一句 A flower cannot blossom without sunshine, and man cannot live without love. 花没有阳光就不能盛开,人没有爱就不能生 ...
- Leetcode 240.搜索二维矩阵II
搜索二维矩阵II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有 ...
- leetcode 240搜索二维矩阵
/** 正常的二维搜索估计要超时,本题沿着对角线搜索,然后找到第一个大于目标数字的坐标(x,y)然后搜索(>x,<y)(<x,>y)子区域: 矩阵size() 为m,n:当i& ...
随机推荐
- .NET Core - 自定义项目模板
前言: 前面介绍 自定义项目模板 中介绍了一种简单的方式--通过创建项目导出为项目模板方式实现.本次将采用dotenet cil(手脚架)来创建项目模板. 那么,我们首先看下当前dotnet 支持的项 ...
- zabbix容器化安装及监控docker应用
一.zabbix agent2 介绍 从Zabbix 4.4之后,官方推出了Zabbix Agent 2,意味着zabbix 不在只是物理机监控的代名词,现在你可以使用Go为Zabbix编写插件,来监 ...
- 基于MATLAB的手写公式识别(2)
基于MATLAB的手写公式识别 图像的预处理(除去噪声.得到后续定位分割所需的信息.) 预处理其本质就是去除不需要的噪声信息,得到后续定位分割所需要的图像信息.图像信息在采集的过程中由于天气环境的影响 ...
- 从零开始使用git将本地项目上传到GitHub
直接进入主题 1. 注册GitHub(官网:https://github.com/),打开官网,右上角点击sign up注册按钮,进入注册界面,根据提示填写信息注册.
- miui10 刷机
起因 折腾一下老手机 名词解释 名称 内容 含义 REC Recovery的缩写 Android出厂时自带的恢复模式 (理解为win PE) 双清 data,cache 用户数据+系统缓存 三清 da ...
- CentOS8 安装 MySQL8.0(yum)
1.Mysql 官网下载 RPM 包wget https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm2.检查是否已安装 ...
- POJ1789简单小生成树
题意: 给你一些车牌号,然后另一两个车牌号之间的权值就是这两个字符串之间相同位置不同字母的个数,然后求最小生成树. 思路: 裸题,不解释了. #include<stdio ...
- Windows核心编程 第十八章 堆栈
第1 8章 堆 栈 对内存进行操作的第三个机制是使用堆栈.堆栈可以用来分配许多较小的数据块.例如,若要对链接表和链接树进行管理,最好的方法是使用堆栈,而不是第 1 5章介绍的虚拟内存操作方法或第1 7 ...
- 学生免费使用JetBrains全家桶
今天又有一个同学来问我申请流程,因此也就趁着这个机会把整个流程简单地记录一下,供大家分享.下面所提及到的学校邮箱以及相关的操作都是以自己学校为准,学校不同可能会稍有不同,大家按自己学校的操作就好. 学 ...
- CCNA 第四章 轻松划分子网
1:划分子网的的好处: (1):减少网络流量 (2):优化网络性能 (3):简化管理 (4):有助于覆盖大型地理区域 2:CIDR和ISP的概念 (1):CIDR:Classless Inter-Do ...