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

相關文章
相關標籤/搜索