103.编辑距离
题目链接
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/edit-distance
题目描述
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例 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')
exection -> execution (插入 'u')
重难点
- 动态规划
- 状态转移方程
题目分析
- 定义二维数组并初始化;
- dp[i][j]表示:word1的前i个字母要转成word2的前j个字母所需的最小操作数;
- dp状态转移方程:若word1[i-1] == word2[j-1] ,dp状态转移方程:dp[i-1][j-1];若word1[i-1] != word2[j-1] ,dp状态转移方程:Math.min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]) + 1,其中:dp[i-1][j] 表示删除操作,dp[i][j-1] 表示插入操作,dp[i-1][j-1] 表示替换操作;
-
如果i*j==0,即有一个单词为0,直接返回i+j;
/** * @param {string} word1 * @param {string} word2 * @return {number} */ var minDistance = function(word1, word2) { let n = word1.length; let m = word2.length; let dp = []; for(let i=0;i<=n;i++){ dp.push([]); for(let j=0;j<=m;j++){ if(i * j){ dp[i][j] = word1[i-1] == word2[j-1] ? dp[i-1][j-1] : (Math.min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1); }else{ dp[i][j] = i+j; } } } return dp[n][m]; };
104.两个字符串的删除操作
题目链接
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/delete-operation-for-two-strings
题目描述
给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。
示例:
输入: "sea", "eat"
输出: 2
解释: 第一步将"sea"变为"ea",第二步将"eat"变为"ea"
提示:
给定单词的长度不超过500。
给定单词中的字符只含有小写字母。
重难点
- 动态规划
- 状态转移方程
题目分析
- 定义二维数组并初始化;
- dp[i][j]表示:找到word1的前i个字母和word2的前j个字母相同的最小步数;
- dp状态转移方程:若word1[i-1] == word2[j-1] ,dp状态转移方程:dp[i-1][j-1];若word1[i-1] != word2[j-1] ,dp状态转移方程:Math.min(dp[i-1][j],dp[i][j-1]) + 1;
-
如果i*j==0,即有一个单词为0,直接返回i+j;
/** * @param {string} word1 * @param {string} word2 * @return {number} */ var minDistance = function(word1, word2) { let n = word1.length; let m = word2.length; let dp = []; for(let i=0;i<=n;i++){ dp.push([]); for(let j=0;j<=m;j++){ if(i * j){ dp[i][j] = word1[i-1] == word2[j-1] ? dp[i-1][j-1] : (Math.min(dp[i-1][j],dp[i][j-1])+1); }else{ dp[i][j] = i+j; } } } return dp[n][m]; };
105.不相交的线
题目链接
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/uncrossed-lines
题目描述
我们在两条独立的水平线上按给定的顺序写下 A 和 B 中的整数。
现在,我们可以绘制一些连接两个数字 A[i] 和 B[j] 的直线,只要 A[i] == B[j],且我们绘制的直线不与任何其他连线(非水平线)相交。
以这种方法绘制线条,并返回我们可以绘制的最大连线数。
示例 1:
输入:A = [1,4,2], B = [1,2,4]
输出:2
解释:
我们可以画出两条不交叉的线,如上图所示。
我们无法画出第三条不相交的直线,因为从 A[1]=4 到 B[2]=4 的直线将与从 A[2]=2 到 B[1]=2 的直线相交。
示例 2:
输入:A = [2,5,1,2,5], B = [10,5,2,1,5,2]
输出:3
示例 3:
输入:A = [1,3,7,1,7,5], B = [1,9,2,5,1]
输出:2
提示:
1 <= A.length <= 500
1 <= B.length <= 500
1 <= A[i], B[i] <= 2000
重难点
- 动态规划
- 状态转移方程
题目分析
- 定义二维数组并初始化;
- dp[i][j]表示:A的前i条线要连接B的前j条线最大的不相交连接数;
- 如果i*j!=0,两组线都存在,计算dp状态转移方程;
- dp状态转移方程:若A[i-1] == B[j-1] ,dp状态转移方程:dp[i-1][j-1]+1;若A[i-1] != B[j-1] ,dp状态转移方程:Math.min(dp[i-1][j],dp[i][j-1])。
/** * @param {number[]} A * @param {number[]} B * @return {number} */ var maxUncrossedLines = function(A, B) { let n = A.length; let m = B.length; let dp = []; for(let i=0;i<=n;i++){ dp[i] = new Array(); for(let j=0;j<=m;j++){ dp[i][j] = 0; } } for(let i=0;i<=n;i++){ for(let j=0;j<=m;j++){ if(i * j){ dp[i][j] = A[i-1] == B[j-1] ? dp[i-1][j-1]+1 : Math.max(dp[i-1][j],dp[i][j-1]); } } } return dp[n][m]; };