[Leedcode][JAVA][第72题][动态规划]

【问题描述】 [72. 编辑距离]

给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。你可以对一个单词进行如下三种操作:插入一个字符
删除一个字符
替换一个字符示例 1:输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')

【解答思路】

1.动态规划

第 1 步:定义状态
状态:dp[i][j] 表示将 word1[0, i) 转换成为 word2[0, j) 的方案数。

思考状态的方法:1、题目问什么就将什么定义为状态;2、「状态转移方程」怎么好推导,就怎么定义状态;3、根据经验和问题的特点(只有多做题了)。

说明:由于要考虑空字符,这里的下标 i 不包括 word[i],同理下标 j 不包括 word[j],从行数和列数多设置一行、一列也可以来理解这一点,也就是状态的下标 i 和 j 和字符的下标 i、j 有一个位置的偏差。

第 2 步:思考状态转移方程
状态转移方程通常是在做分类讨论,而分类讨论的过程,常常利用了这个问题的「最优子结构」。

情况 1:word1[i] == word2[j]
如果 word1[i] == word2[j] 成立,则将 word1[0, i) 转换成为 word2[0, j) 的方案数就等于 将 word1[0, i - 1) 转换成为 word2[0, j - 1) 的方案数,即:

dp[i + 1][j + 1] = dp[i][j];
注意:这种情况,方案数最少,后面三种情况可以不用讨论,在这里暂时忽略。

情况 2:word1[i] != word2[j]
如果 word1[i] != word2[j] ,则将 word1[0, i) 转换成为 word2[0, j) 的方案数就等于下面 3 种情况的最少操作数(「最优子结构」):

考虑修改 word1[i] 成为 word2[j];
此时 dp[i + 1][j + 1] = dp[i][j] + 1,这里的 1 代表了将 word1[i] 替换成为 word2[j] 这一步操作。

考虑将 word1[0, i] 的最后一个字符删除;
此时 word1[0, i - 1] 到 word2[0, j] 的最少操作数 + 1+1,就是这种方案数的最少操作数,即: dp[i + 1][j + 1] = dp[i][j + 1] + 1,这里的 1 代表了 word1[0, i] 的最后一个字符删除这一步操作。

考虑将 word1[0, i] 的末尾添加一个字符使得 word1[i + 1] == word2[j];
此时考虑方案的时候,由于 word1[i + 1] == word2[j],状态转移就不应该考虑 word2[j],因此 word1[0, i] 到 word2[0, j - 1] 的最少操作数 + 1+1,就是这种方案数的最少操作数,即: dp[i + 1][j + 1] = dp[i + 1][j] + 1,这里的 1 代表了将 word1[0, i] 的末尾添加一个字符使得 word1[i + 1] == word2[j]。(注意:可以考虑一下为什么得先讨论 word1[i] == word2[j] 的情况。)

在这 3 种操作中取最小值。

dp[i + 1][j + 1] = min(dp[i][j], dp[i][j + 1], dp[i + 1][j]) + 1

第 3 步:初始化
从一个字符串变成空字符串,非空字符串的长度就是编辑距离;
以下代码其实就是在填表格的第 00 行、第 00 列。

for (int i = 0; i <= len1; i++) {dp[i][0] = i;
}for (int j = 0; j <= len2; j++) {dp[0][j] = j;
}

第 4 步: 思考输出
输出:dp[len1][len2] 符合语义,即 word1[0, len) 转换成 word2[0, len2) 的最小操作数。(这里 ) 表示开区间。)

第 5 步: 思考状态压缩
我们看一下「状态转移方程」:

  • 如果末尾字符相等,就「抄」左上角单元格的值;
  • 如果末尾字符不相等,就从「正上方」、「左边」、「左上角」三个单元格的值中选出最小的 + 1。
    因此,初看可以使用「滚动数组」,更极端一点,用 2 \times 22×2 表格就可以完成操作。但是真正去做「状态压缩」的时候,由于初始化的原因,发现没有那么容易,在这里不做「状态压缩」。(事实上可以压缩,但是只要是压缩状态,必然给编码造成一定困难,并且破坏代码可读性,根据情况做吧,个人觉得在空间紧张的情况下必须压缩空间,其余不必。)

手填

时间复杂度:O(N^2) 空间复杂度:O(N)

import java.util.Arrays;public class Solution {public int minDistance(String word1, String word2) {// 由于 word1.charAt(i) 操作会去检查下标是否越界,因此// 在 Java 里,将字符串转换成字符数组是常见额操作char[] word1Array = word1.toCharArray();char[] word2Array = word2.toCharArray();int len1 = word1Array.length;int len2 = word2Array.length;// 多开一行一列是为了保存边界条件,即字符长度为 0 的情况,这一点在字符串的动态规划问题中比较常见int[][] dp = new int[len1 + 1][len2 + 1];// 初始化:当 word 2 长度为 0 时,将 word1 的全部删除for (int i = 1; i <= len1; i++) {dp[i][0] = i;}// 当 word1 长度为 0 时,就插入所有 word2 的字符for (int j = 1; j <= len2; j++) {dp[0][j] = j;}// 注意:填写 dp 数组的时候,由于初始化多设置了一行一列,横、纵坐标有个偏移for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 这是最佳情况if (word1Array[i] == word2Array[j]) {dp[i + 1][j + 1] = dp[i][j];continue;}// 否则在以下三种情况中选出步骤最少的,这是「动态规划」的「最优子结构」// 1、在下标 i 处插入一个字符int insert = dp[i + 1][j] + 1;// 2、替换一个字符int replace = dp[i][j] + 1;// 3、删除一个字符int delete = dp[i][j + 1] + 1;dp[i + 1][j + 1] = Math.min(Math.min(insert, replace), delete);}}// 打印状态表格进行调试
//        for (int i = 0; i <=len1; i++) {
//            System.out.println(Arrays.toString(dp[i]));
//        }return dp[len1][len2];}public static void main(String[] args) {String word1 = "horse";String word2 = "ros";Solution solution = new Solution();int res = solution.minDistance(word1, word2);System.out.println(res);}
}作者:liweiwei1419
链接:https://leetcode-cn.com/problems/edit-distance/solution/dong-tai-gui-hua-java-by-liweiwei1419/

【总结】

  1. 动态规划
  • 「自底向上」去考虑一个问题
    思考的时候可以先将大区间拆分成小区间,求解的时候由小区间的解得到大区间的解。
  1. 「动态规划」求解的问题的三个特征:
  • 重叠子问题
  • 最优子结构
  • 无后效性
  1. 动态规划解题步骤
    第 1 步:定义状态
    第 2 步:思考状态转移方程
    第 3 步:初始化
    第 4 步: 思考输出
    第 5 步: 思考状态压缩

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/426040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java学习(145):file常用方法2

import java.io.File; import java.io.IOException; import java.net.URI; import java.util.List;//文件管理类 public class FileManager {public static File createFileAction(URI uri){//使用URI做出参数创建对象if(uri!null)return new File( uri );return null;}//dir文…

java uipath_10.3 UiPath如何调用Java

调用Java方法(Invoke Java Method)的介绍从Java Scope中的.jar加载的方法中调用指定的Java方法。并结果存储在变量中二、Invoke Java Method 在UiPath中的使用打开设计器, 在设计库中新建一个Sequence&#xff0c;为序列命名及设置Sequence存放的路径, 在Activities中搜索Java …

java学习(146):file常用方法3

import java.io.File; import java.io.IOException; import java.net.URI; import java.util.List;//文件管理类 public class FileManager {public static File createFileAction(URI uri){//使用URI做出参数创建对象if(uri!null)return new File( uri );return null;}//dir文…

[算法][二分查找][排除法]

最基本的二分查找算法 「搜索区间」是 [left, right] nums[mid] target 时可以立即返回 int binary_search(int[] nums, int target) {int left 0, right nums.length - 1; while(left < right) {int mid left (right - left) / 2;//防止大数溢出if (nums[mid] < t…

java学习(147):字节输入流

//读取二进制文件&#xff0c;字节输入流 import java.io.*;public class FileMana {public static void readBitFile(String filename){//1建立目标要读取的文件对象File filenew File( filename );//2基于目标对象建立输入流InputStream innull;if(file.exists()){//如果文件…

[Leedcode][JAVA][面试题 01.07][找规律][旋转数组]

【问题描述】 [面试题 01.07. 旋转矩阵] 示例 1:给定 matrix [[1,2,3],[4,5,6],[7,8,9] ],原地旋转输入矩阵&#xff0c;使其变为: [[7,4,1],[8,5,2],[9,6,3] ]给你一幅由 N N 矩阵表示的图像&#xff0c;其中每个像素的大小为 4 字节。请你设计一种算法&#xff0c;将图像…

java学习(148):三个参数的输入流

//3个参数读取二进制文件 import java.io.*;public class FileManage {public static void readBitFile(String filename){//1建立目标要读取的文件对象File filenew File( filename );//2基于目标对象建立输入流InputStream innull;if(file.exists()){//如果文件存在&#xff…

[剑指offer][JAVA][面试题第13题][机器人的运动][DFS][BFS]

【问题描述】 [中等] 地上有一个m行n列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&#xff0c;也不能进入行坐标和列坐标的数位之和…

ios php rsa,RSA 加密 iOS

在iOS端使用RSA加密的记录一、需求&#xff1a;SDK开发&#xff0c;使用RSA加密和后台进行数据交互&#xff0c;后台是PHP要求&#xff1a;1、post请求&#xff0c;客户端放公钥&#xff0c;私钥放后台2、发送数据&#xff1a;客户端的json数据—>RSA加密数据—>base64编…

java学习(149):字符输入流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

java三年,Java开发三年,你不得不了解的JVM(一)

基本概念&#xff1a;JVM 是可运行 Java 代码的假想计算机 &#xff0c;包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收&#xff0c;堆 和 一个存储方法域。JVM 是运行在操作系统之上的&#xff0c;它与硬件没有直接的交互。运行过程&#xff1a;我们都知道Java源文件…

[Leedcode][JAVA][第22题括号生成][DFS][BFS][动态规划]

【问题描述】22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例&#xff1a;输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()","()(…

java学习(150):文本缓冲流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

微信小程序初始化 operateWXData:fail invalid scope

初学者开发微信小程序&#xff0c;可以使用云开发来进行微信小程序的开发。 第一次使用开发工具遇到的问题 解决方案&#xff1a;1、找到云开发 2、点击开通&#xff0c;选择合适自己的开发环境&#xff1b; 3、完成后&#xff0c;返回开发工具界面点击项目第一个节点“cloudfu…

matlab win10 gpu加速,win10的Edge浏览器设置GPU硬件加速,大幅度提升浏览器性能

不知道大家对于GPU硬件加速是否有了解&#xff0c;这是现在的浏览器必备的功能&#xff0c;开启后能大幅度提升浏览器的性能&#xff0c;给我们更加顺滑的浏览体验。GPU硬件加速能够利用GPU的图形性能&#xff0c;加速渲染网页中的图像信息。如果我们开启了GPU硬件加速&#xf…

java学习(151):字节输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][第887题][鸡蛋掉落][谷歌面试][动态规划]

【问题描述】 [887. 鸡蛋掉落] 你将获得 K 个鸡蛋&#xff0c;并可以使用一栋从 1 到 N 共有 N 层楼的建筑。每个蛋的功能都是一样的&#xff0c;如果一个蛋碎了&#xff0c;你就不能再把它掉下去。你知道存在楼层 F &#xff0c;满足 0 < F < N 任何从高于 F 的楼层落…

java学习(152):字节缓冲输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

SDUTOJ3469_深度优先搜索练习之神奇的矩环(DFS)

深度优先搜索练习之神奇的矩环 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 小鑫的女朋友被魔王抢走了&#xff01; 魔王留给小鑫一张n*m大的表&#xff0c;上面有各种各样的颜色&#xff0c;用A-Z这26个字母来表示。魔王留给他一个任务…

PHP水果店管理系统,水果店连锁店管理系统实现一体化功能

现在的人们越来越注重养生&#xff0c;特别是饮食养生那么水果就成为了客户的首选之一&#xff0c;随着水果的市场需求越来越大&#xff0c;想开水果店的创业者越来越多&#xff0c;连锁水果店我们看到的店面也越来越多&#xff0c;由于季节或者是时间的问题会很容易导致水果变…