Edit Distance

Edit Distance 题解


题目描述

Edit Distance
即寻找两个字符串之间的编辑距离。编辑距离定义函数

编辑距离是针对二个字符串(例如英文字)的差别程度的量化量测,量测方式是看至少须要多少次的处理才能将一个字符串变成另外一个字符串。

如:kittensitting的最小编辑距离是3。spa

  1. kitten → sitten(k→s)
  2. sitten → sittin(e→i)
  3. sittin → sitting(+g)

题解

经典动态规划问题。将长度为m字符串S变成长度为n字符串T,其状态转移方程为:code

$$ f(i,j) = \begin{cases} \sum_{k=1}^i CostOfDel(T_k) & \text{if $j = 0$ } \\[2ex] \sum_{k=1}^j CostOfIns(S_k) & \text{if $i = 0$ } \\[2ex] min \begin{cases} f(i-1,j)+CostOfDel(T_i) \\[2ex] f(i,j-1)+CostOfIns(S_j) \\[2ex] f(i-1,j-1)+CostOfSub(S_j,T_i) & \text{if $S_j \neq T_i$ } \\[2ex] f(i-1,j-1) & \text{if $S_j = T_i$ } \\[2ex] \end{cases} & \text{ others } \\[2ex] \end{cases} $$ip

f(i,j) 表明字符串S的长度为j的前缀子串变成字符串T的长度为i的前缀子串的最小编辑代价。leetcode

答案即f(n,m)。状态数mn个,状态转移复杂度O(1),所以时间复杂度为O(mn),空间复杂度为O(min(m,n))
此题中全部Cost*函数的返回值都是1。则状态转移方程可简化为字符串

$$ f(i,j) = \begin{cases} i & \text{if $j = 0$ } \\[2ex] j & \text{if $i = 0$ } \\[2ex] f(i-1,j-1) & \text{if $S_j = T_i$ } \\[2ex] min \begin{cases} f(i-1,j)+1 \\[2ex] f(i,j-1)+1 \\[2ex] f(i-1,j-1)+1 \\[2ex] \end{cases} & \text{if $S_j \neq T_i$ } \\[2ex] \end{cases} $$get

代码

#include <algorithm>

class Solution {
    typedef int len_type;
public:
    int minDistance(const string& src, const string& dest) {
        if (dest.size() > src.size()) {
            return minDistance(dest, src);
        }
        if (!dest.size())
            return src.size();
        if (!src.size())
            return dest.size();
        len_type len_src = src.size(), len_dest = dest.size();
        len_type* const pc = new len_type[len_dest];
        char c = src[0];
        pc[0] = (c != dest[0]);
        for (len_type j = 1; j < len_dest; ++j)
            pc[j] = std::min((c != dest[j]) + j, pc[j - 1] + 1);
        for (len_type i = 1; i < len_src; ++i) {
            char c = src[i];
            len_type lastj = pc[0];
            pc[0] = std::min((c != dest[0]) + i, lastj + 1);
            for (len_type j = 1; j < len_dest; ++j) {
                len_type samej = pc[j];
                pc[j] = std::min((c != dest[j]) + lastj, std::min(pc[j - 1], samej) + 1);
                lastj = samej;
            }
        }
        len_type dist = pc[len_dest - 1U];
        delete [] pc;
        return dist;
    }
};

总结

主要应用了动态规划的思想。string

相关文章
相关标签/搜索