字节面试:编辑距离该怎么求?

大家好,我是涛哥。

又是周末,过去的几天工作日,可能你会忙得焦头乱额,但毕竟是充实的,忙碌才是生活和工作的常态,也值得欣慰。

今天,我们来聊一个经典的面试题:编辑距离。无论是面试字节跳动、腾讯还是阿里,编辑距离必须掌握,且要熟练写出代码。

图片

                                              涛哥手绘(老虎与猫的编辑距离)

一. 编辑距离简介

编辑距离,可以用于度量两个字符串的差异。其含义是:一个字符串到另一个字符串的最少变换次数,其中,变换操作仅涉及增删改,且每次只能操作一个字符。

编辑距离的应用很广,比如常见的纠错检错原理:当你在浏览器输入错误单词ggood后,通过编辑距离匹配,能自动给你提示出正确的单词good, 挺有用的吧?

图片

  

二. 编辑距离题目

编辑距离,在笔试面试中会经常涉及到。一个朋友最近参加了字节跳动公司的面试,便遇到了编辑距离,题目如下:

实话实话,如果没有提前准备,那么现场是很难想出解题思路的,也就别谈通过面试了。有些东西,必须提前准备,知己知彼,方能百战不殆。   

三. 编辑距离算法

编辑距离,是一个典型的动态规划问题。那么,从一个字符串到另一个字符串的编辑距离一定存在吗?这是必然的,暴力方法可以证明,不必赘述。

记dp[i][j]为字符串A的前i个字符到字符串B的前j个字符的编辑距离,如果A或B为空串,那么i或j为0,因此i的区间为[0, lenA], j的区间为[0, lenB]. 

接下来,我们来推导动态规划的状态转移方程。

(1) 如果A[i]等于B[j], 那么此时便是躺赢的模式,即有:

dp[i][j] = dp[i-1][j-1]

(2) 如果A[i]不等于B[j], 则可以进行三种操作(增删改),如下:

  • 把A的前i-1个字符变成B的前j个字符,然后删除一个字符;

  • 把A的前i个字符变成B的前j-1个字符,然后增加一个字符;

  • 把A的前i-1个字符变成B的前j-1个字符,然后改变一个字符;

显然,此时的动态规划方程为:

dp[i][j] = 1 +

min{dp[i-1][j],dp[i][j-1],dp[i-1][j-1]}

四. 编辑距离编程        

算法搞懂后,程序就简单了,我们以golang代码为例来编程:

func minDistance(A string, B string) int {    lenA := len(A)    lenB := len(B)
    // 初始化二维slice    dp := make([][]int, lenA + 1)    for i := 0; i < lenA + 1; i++ {        dp[i] = make([]int, lenB + 1)    }    for i := 0; i < lenA + 1; i++ {        dp[i][0] = i    }    for j := 0; j < lenB + 1; j++ {        dp[0][j] = j    }    for i := 1; i < lenA + 1; i++ {        for j := 1; j < lenB + 1; j++ {            if A[i - 1] == B[j - 1] {                dp[i][j] = dp[i-1][j-1]            }else {                dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])            }        }    }    return dp[lenA][lenB]}
func min(x, y, z int) int {    m := x    if x > y {        m = y    }    if m > z {        m = z    }    return m}

经自测,程序通过,结果无误。从算法到代码实现,都是OK的,能通过面试。

到此为止,我们对编辑距离的求法有了彻底的掌握,也顺便和大家一起复习了动态规划的内容。

希望大家在面试前要专门地准备,既然大厂爱考这些,又提供那么高的工资,那就好好准备吧。

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值