LeetCode #72 Edit Distance - 刷題之旅
1 題目描述
給定兩個單詞word1
和word2
,找到將word1
轉換為word2
所需的最小操作數。
- 操作包括插入一個字符、刪除一個字符、替換一個字符
- 美的操作的成本是1
2 解法
我會建議先畫出一個dp圖,這個dp代表,word1
的前i
個字元與word2
的前j
個字元的最小操作數,這樣就可以從dp[i-1][j-1]
推導出dp[i][j]
。
你會發現,第一列或是第一排,也就是word1
或word2
為空的時候,最小操作數就是當前字元的長度,可以透過這個特性來初始化dp
。
如上圖所示,可以寫出以下程式碼進行初始化:
1 | class Solution: |
接下來,我們先來使用一個比較簡單的例子來說明一下會有哪些狀況:
- 當
word1[i] == word2[j]
時,不需要進行任何操作,繼續往下一個字元比較即可(i+1,j+1)
這會對應到dp[i][j] = dp[i-1][j-1]
- 當
word1[i] != word2[j]
時,有三種操作方式:- 插入:
(i,j+1)
這會對應到dp[i][j-1] + 1
- 刪除:
(i+1,j)
這會對應到dp[i-1][j] + 1
- 替換:
(i+1,j+1)
這會對應到dp[i-1][j-1] + 1
- 插入:
我來說明為什麼會這樣對應:
情境1:當比較的字元相同時
從上圖你會發現,如果我們求dp[3][5]
時,因為word1[3-1] == word2[5-1] == "s"
,所以我們看能有三種操作方式,但是上面的操作方式中,只有從斜方向來的成本最小,因為當下比較的字元是相同的,所以我們不需要進行任何操作,可以直接取dp[2][4]
的值。如果我們硬要取上面或是左邊的值,那就會多一次操作。
情境2:當比較的字元不同時
從上圖如果我們求dp[3][4]
時,因為word1[3-1] != word2[4-1]
,所以我們看能有三種操作方式,上面三種操作方式中我們要取最小的。從這個例子裡面,斜角或是左邊的值是最小的。
共通點
然後你會發現這三個操作的公式如下:
- 上面(插入):
dp[i][j-1] + 1
- 左邊(刪除):
dp[i-1][j] + 1
- 斜角(替換):
dp[i-1][j-1] + 1
(當前字元不同)或dp[i-1][j-1]
(當前字元相同)
這樣我們就可以寫出以下程式碼:
1 | class Solution: |
3 總結
這題花蠻多時間時考的,下次碰到類似的題目一率建議先把dp表畫出來,這樣會比較好理解。慢慢推倒就可以抓到公式了。
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Shannon's Blog 🐟 技術 | 生活 | 旅行! 如果你覺得我的文章有幫助,希望你可以到我的 github 給我一個 star ⭐️ Shannon Blog Repo
評論