12. 最大UCC子串计算
问题描述
一、题目解析
解题思路
本题要求我们在给定的编辑距离限制下,尽可能多地在字符串中找到 "UCC" 子串。编辑距离定义为将字符串 S 转化为其他字符串时所需的最少编辑操作次数,包括插入、删除或替换单个字符。我们需要计算在给定的编辑距离限制 m 下,能够包含最多 "UCC" 子串的字符串可能包含多少个这样的子串。
-
问题理解:
- 本题要求在给定的编辑距离限制下,尽可能多地找到子串
"UCC"。 - 需要考虑插入、删除和替换操作对子串
"UCC"的影响。
- 本题要求在给定的编辑距离限制下,尽可能多地找到子串
-
DP表设计:
dp[i][j]表示前i个字符的字符串在编辑距离为j的情况下,最多能包含多少个"UCC"子串。- 需要考虑三种操作(插入、删除、替换)对
dp[i][j]的影响。
-
状态转移:
- 不进行任何操作:
dp[i][j] = dp[i-1][j] - 插入操作:
dp[i][j] = max(dp[i][j], dp[i][j-1]) - 删除操作:
dp[i][j] = max(dp[i][j], dp[i-1][j-1]) - 替换操作:
dp[i][j] = max(dp[i][j], dp[i-3][j-3] + 1)如果s[i-3:i] == "UCC"
- 不进行任何操作:
实现步骤
- 初始化一个二维数组 dp,其中 dp[i][j] 表示前 i 个字符的字符串在编辑距离为 j 的情况下,最多能包含多少个 "UCC" 子串。
- 遍历字符串,对于每个字符,考虑不进行操作、插入操作、删除操作和替换操作对 dp 值的影响。
- 特别地,当遇到 "UCC" 子串时,如果编辑距离允许,可以增加一个 "UCC" 子串的数量。
Python 代码实现
def solution(m: int, s: str) -> int:
n = len(s)
# dp[i][j] 表示前 i 个字符的字符串在编辑距离为 j 的情况下,最多能包含多少个 "UCC" 子串
dp = [[0] * (m + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for j in range(m + 1):
# 不进行任何操作
dp[i][j] = dp[i - 1][j]
# 考虑插入操作
if j >= 1:
dp[i][j] = max(dp[i][j], dp[i][j - 1])
# 考虑删除操作
if i >= 1 and j >= 1:
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1])
# 考虑替换操作
if i >= 3 and j >= 3 and s[i - 3:i] == "UCC":
dp[i][j] = max(dp[i][j], dp[i - 3][j - 3] + 1)
return dp[n][m]
# 测试用例
if __name__ == '__main__':
print(solution(m=3, s="UCUUCCCCC") == 3)
print(solution(m=6, s="U") == 2)
print(solution(m=2, s="UCCUUU") == 2)
二、知识总结
在实现这道题的过程中,结合豆包 MarsCode AI 刷题功能,总结了以下知识点:
-
动态规划的应用:本题是一个典型的动态规划问题,通过构建 dp 数组来存储子问题的解,避免了重复计算,提高了解题效率。
-
字符串处理:在处理字符串时,需要对子串进行比较和匹配,这是处理字符串问题的基本技能。
三、总结
通过这道题,我不仅熟悉了动态规划和字符串处理的应用,还复习了Python编程基础。这道题主要考察了对动态规划的理解和应用,同时也考察了对字符串操作和编辑距离概念的理解。希望这篇笔记能为大家提供帮助,也期待与各位在刷题路上共同进步!