72. Edit Distance
MediumDescription
給定兩個字串
word1和word2,回傳將word1轉換成word2所需的最少操作次數。允許的操作:插入一個字元、刪除一個字元、替換一個字元。
Example:
Input: word1 = “horse”, word2 = “ros” Output: 3 (horse -> rorse -> rose -> ros)
Intuition#
- 若
word1[i-1] == word2[j-1]:dp[i][j] = dp[i-1][j-1](不需操作) - 否則取三種操作的最小值 +1:
dp[i-1][j-1] + 1:替換dp[i-1][j] + 1:刪除 word1 的字元dp[i][j-1] + 1:插入字元到 word1
- 基底:
dp[i][0] = i(全部刪除),dp[0][j] = j(全部插入)
Approaches#
1: 2D DP Table#
- 概念: 建立
(m+1) x (n+1)的表格,按照轉移方程填寫。 - 時間複雜度:
O(m * n) - 空間複雜度:
O(m * n)
class Solution {
fun minDistance(word1: String, word2: String): Int {
val m = word1.length
val n = word2.length
val dp = Array(m + 1) { IntArray(n + 1) }
for (i in 0..m) dp[i][0] = i
for (j in 0..n) dp[0][j] = j
for (i in 1..m) {
for (j in 1..n) {
dp[i][j] = if (word1[i - 1] == word2[j - 1]) {
dp[i - 1][j - 1]
} else {
minOf(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1
}
}
}
return dp[m][n]
}
}⭐2: 1D DP(空間優化)#
- 概念: 用一維陣列加
prev變數保存左上角的值。 - 時間複雜度:
O(m * n) - 空間複雜度:
O(n)
class Solution {
fun minDistance(word1: String, word2: String): Int {
val m = word1.length
val n = word2.length
val dp = IntArray(n + 1) { it }
for (i in 1..m) {
var prev = dp[0]
dp[0] = i
for (j in 1..n) {
val temp = dp[j]
dp[j] = if (word1[i - 1] == word2[j - 1]) {
prev
} else {
minOf(prev, dp[j], dp[j - 1]) + 1
}
prev = temp
}
}
return dp[n]
}
}🔑 Takeaways#
- Pattern: 雙字串 DP — 插入/刪除/替換三種操作對應三個方向的轉移
- 關鍵技巧: Edit Distance 是 NLP、拼寫檢查的基礎演算法;空間優化的
prev變數技巧在多題中重複出現