华为OD面试手撕代码:编辑距离

题目

编辑距离

给你两个单词 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')

提示:

  • 0 <= word1.length, word2.length <= 500
  • word1 和 word2 由小写英文字母组成

代码

/*
编辑距离问题是一个经典的动态规划(Dynamic Programming)问题。我们可以使用动态规划来解决这个问题,其中状态转移方程可以描述为:

1. 如果 word1[i] 等于 word2[j],则 dp[i][j] = dp[i-1][j-1],即不进行任何操作,保持相同。
2. 如果 word1[i] 不等于 word2[j],则可以进行三种操作中的一种:
    插入:dp[i][j] = dp[i][j-1] + 1,即在 word1[i] 后插入一个与 word2[j] 相同的字符,使 word1 和 word2 相同。
    删除:dp[i][j] = dp[i-1][j] + 1,即删除 word1[i],使 word1 和 word2 相同。
    替换:dp[i][j] = dp[i-1][j-1] + 1,即将 word1[i] 替换为 word2[j],使 word1 和 word2 相同。
 */
public class Main {
    public static void main(String[] args) {
        Solution solution = new Solution();

        // 示例 1
        String word1 = "horse";
        String word2 = "ros";
        int result1 = solution.minDistance(word1, word2);
        System.out.println("示例 1 输出:" + result1); // 输出:3

        // 示例 2
        String word3 = "intention";
        String word4 = "execution";
        int result2 = solution.minDistance(word3, word4);
        System.out.println("示例 2 输出:" + result2); // 输出:5
    }
}

class Solution {
    /**
     * 计算两个字符串的最小编辑距离
     * 编辑距离指的是将一个字符串转换成另一个字符串所需要的最少操作次数,操作包括插入一个字符、删除一个字符、替换一个字符
     *
     * @param word1 第一个字符串
     * @param word2 第二个字符串
     * @return 两个字符串的最小编辑距离
     */
    public int minDistance(String word1, String word2) {
        int m = word1.length(); // word1的长度
        int n = word2.length(); // word2的长度

        // 创建二维数组dp,dp[i][j]表示将word1的前i个字符转换为word2的前j个字符所需的最少操作数
        int[][] dp = new int[m + 1][n + 1];

        // 初始化第一行和第一列
        for (int i = 0; i <= m; i++) {
            dp[i][0] = i;
        }
        for (int j = 0; j <= n; j++) {
            dp[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)) {
                    dp[i][j] = dp[i - 1][j - 1]; // 当两个字符相等时,不需要进行任何操作
                } else {
                    // 当两个字符不相等时,选择插入、删除、替换操作中需要的最小次数,并加1
                    dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i][j - 1], dp[i - 1][j])) + 1;
                }
            }
        }

        return dp[m][n]; // 返回最小编辑距离
    }
}
全部评论
真不错,感谢分享
点赞
送花
回复 分享
发布于 06-23 12:18 江苏

相关推荐

#软件开发笔面经#华为od有机考、资格面、心理测评、技术一面、技术二面、主管面。我从三月准备机试,到四月底进行。机考一共三道题,分数分别是100、100、200.按照测试用例进行给分。目标院校需要150+,非目标院校需要300+,作答的语言没有限制,但最好是和后面面试的岗位保持一致。资格面主要询问个人意向情况,一般在半小时以内。心理测评主要考察前后问题答案的一致性。技术一面会问一些八股,然后有一道手撕代码,差不多是力扣简单或者中等难度,偶尔也会遇到困难难度,作答语言同样没有限制。八股的话基本上就是该开发语言一些常规的经典问题,花时间刷一刷背一背,谈一点个人的看法就好。技术二面和技术一面类似。面试官会给到面试人员一个等级,如果两次面试评级不一致,会加试技术终面来确定最后的入职级别。主管面的面试官level很高,会让你做自我介绍,对你的项目简要提问,然后询问你的意向程度,问了个人爱好,还有就是od是和德科或科瑞签合同,与华为正式员工和华为公司签合同是不一样的,问你的看法,还有自己在单位的一个长期发展规划,会问到对加班的看法,最后会问你的意向薪酬。告诉面试官之后,他会让我们了解不同地域的用人成本存在差异性,要注重长期发展。或许我们现在以他人为模范,但他日我们亦或会成为他人的标杆。主管面在半小时以内。华为内部有竞业协议,你将身份证号邮箱姓名简历发给HR后会锁简历,后期只能由该HR和你对接指导你进行后续笔面流程。在经历了机考、资格面、心理测评、技术一面、技术二面、主管面之后的我正在等通知ing
点赞 评论 收藏
分享
4 2 评论
分享
牛客网
牛客企业服务