返回
深入分析:以最少字符改变满足三个条件的字符串
后端
2023-10-06 07:12:57
导读
在 LeetCode 的众多算法题中,字符串处理问题一直备受关注。而动态规划法,作为解决这类问题的有力武器,往往能带来事半功倍的效果。今天,我们就一起来探索 LeetCode 上一道中等难度的字符串处理题目 —— 满足三条件之一需改变的最少字符数。
题目
给你两个字符串 s
和 t
,若满足以下三个条件之一,则判定它们 相似 :
s
可以通过删除一些字符(不改变顺序)得到t
。t
可以通过删除一些字符(不改变顺序)得到s
。s
和t
一样。
例如,"abcd"
和 "ad"
是相似的,因为你可以通过删除 s
中的 b
和 c
来得到 t
。
你的任务是找出使 s
和 t
相似所需的最小字符改变数。
示例
输入:s = "ab", t = "acb"
输出:1
解释:你可以通过删除 `t` 中的 `c` 来使 `s` 和 `t` 相似。
输入:s = "acb", t = "abc"
输出:2
解释:你可以通过删除 `s` 中的 `c` 和 `b` 来使 `s` 和 `t` 相似。
动态规划法
这道题目的本质是求解两个字符串之间的最长公共子序列(LCS)。而 LCS 的最优子结构可以通过动态规划法来高效地求解。
具体来说,我们定义 dp[i][j]
为字符串 s
的前 i
个字符和字符串 t
的前 j
个字符的最长公共子序列的长度。那么,我们可以通过以下递推公式来计算 dp[i][j]
:
- 如果
s[i] == t[j]
,则dp[i][j] = dp[i-1][j-1] + 1
。 - 如果
s[i] != t[j]
,则dp[i][j] = max(dp[i-1][j], dp[i][j-1])
。
一旦我们计算出了 dp
数组,那么使 s
和 t
相似所需的最小字符改变数就等于 s.length() + t.length() - 2 * dp[s.length()][t.length()]
。
代码实现
class Solution {
public:
int minDistance(string s, string t) {
int m = s.length();
int n = t.length();
int dp[m+1][n+1];
for (int i = 0; i <= m; i++) {
dp[i][0] = 0;
}
for (int j = 0; j <= n; j++) {
dp[0][j] = 0;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s[i-1] == t[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
} else {
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
}
return s.length() + t.length() - 2 * dp[m][n];
}
};
复杂度分析
- 时间复杂度:
O(mn)
,其中m
和n
分别是字符串s
和t
的长度。 - 空间复杂度:
O(mn)
,用于存储dp
数组。
结语
以上就是 LeetCode 上一道中等难度的字符串处理题目 —— 满足三条件之一需改变的最少字符数 的详细解析。通过使用动态规划法,我们可以高效地求解出使两个字符串相似的最小字符改变数。