zoukankan      html  css  js  c++  java
  • 刷题66(力扣3道题-动态规划)

    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')

    重难点

    1. 动态规划
    2. 状态转移方程

    题目分析

    1. 定义二维数组并初始化;
    2. dp[i][j]表示:word1的前i个字母要转成word2的前j个字母所需的最小操作数;
    3. 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] 表示替换操作;
    4. 如果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。
    给定单词中的字符只含有小写字母。

    重难点

    1. 动态规划
    2. 状态转移方程

    题目分析

    1. 定义二维数组并初始化;
    2. dp[i][j]表示:找到word1的前i个字母和word2的前j个字母相同的最小步数;
    3. 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;
    4. 如果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

    重难点

    1. 动态规划
    2. 状态转移方程

    题目分析

    1. 定义二维数组并初始化;
    2. dp[i][j]表示:A的前i条线要连接B的前j条线最大的不相交连接数;
    3. 如果i*j!=0,两组线都存在,计算dp状态转移方程;
    4. 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];
    };
    

      

  • 相关阅读:
    ZooKeeper的工作原理
    redis 数据类型详解 以及 redis适用场景场合
    nginx负载均衡原理
    Java中缓存的介绍
    Java中接口的作用
    json与xml的区别
    最经典40个多线程问题总结
    Java线程 : 线程同步与锁
    dbcp与c3p0的区别
    Linux常见命令
  • 原文地址:https://www.cnblogs.com/liu-xin1995/p/12642688.html
Copyright © 2011-2022 走看看