문제 링크
요약
- 다음에 다시 풀어보자.
최종
결과
word1의 크기를n1,word2의 크기를n2라고 해보자.- 2차원 DP
dp[n1 + 1][n2 + 1]를 사용하면 된다.- 각 cell 의 의미:
- Substring
word1[0:i]를 substringword2[0:j]로 변경하는 최소 operation 의 횟수가dp[i + 1][j + 1]이다.
- Substring
- 초기화 규칙:
dp[i + 1][0]은word1[0:i]를""로 만드는 비용이다. 따라서 이건 항상i + 1와 같다.- 마찬가지로
dp[0][j + 1]은""를word2[0:j]로 만드는 비용이고, 그래서 항상j + 1와 같다. - 동일한 논리로
dp[0][0]은""을""로 만드는 비용이기 때문에 0이다.
dp[i + 1][j + 1]도출 방법:word1[0:i-1]에서word2[0:j]로 만드는 최소 operation 의 횟수는dp[i][j + 1]이다. 따라서word1[0:i]에서word1[i]를 delete 해서word1[0:i-1]로 만들어 주고, 이를word2[0:j]바꿔주면 된다. 그럼 총 operation 의 횟수는dp[i][j + 1] + 1이다.word1[0:i]에서word2[0:j-1]로 만드는 최소 operation 의 횟수는dp[i + 1][j]이다. 따라서word1[0:i]를word2[0:j-1]로 만들어주고 마지막에word2[j]를 insert 해주면word2[0:j]가 된다. 그럼 총 operation 의 횟수는dp[i + 1][j] + 1이다.word1[0:i-1]에서word2[0:j-1]로 만드는 최소 operation 의 횟수는dp[i][j]이다. 우선word1[0:i]안의word1[0:i-1]substring 을word2[0:j-1]로 바꿔준다. 그리고word1[i]를word2[j]로 replace 해주면word2[0:j]가 된다. 그럼 총 operation 의 횟수는dp[i][j] + 1이다. 다만,word1[i]와word2[j]같으면 replace 해줄 필요가 없다. 따라서 이때는 operation 횟수가dp[i][j]가 된다.
- 각 cell 의 의미:
- 이를 코드로 구현하면 다음과 같다:
class Solution {
public:
int minDistance(string word1, string word2) {
int n1 = word1.size();
int n2 = word2.size();
vector<vector<int>> dp(n1 + 1, vector<int>(n2 + 1));
// (2-1)
for (int i = 0; i < n1; i++) {
dp[i + 1][0] = i + 1;
}
// (2-2)
for (int j = 0; j < n2; j++) {
dp[0][j + 1] = j + 1;
}
// (2-3)
dp[0][0] = 0;
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
int op_delete = dp[i][j + 1] + 1; // (3-1)
int op_insert = dp[i + 1][j] + 1; // (3-2)
int op_replace = dp[i][j]; // (3-3)
op_replace += (word1[i] == word2[j] ? 0 : 1);
dp[i + 1][j + 1] = min(min(op_delete, op_insert), op_replace);
}
}
return dp[n1][n2];
}
};