最少前缀问题刷题笔记
一、题目解析
问题描述
给定两个字符串 S 和 T,需要通过对 S 进行若干次操作,使其变为 T 的前缀。允许的操作包括:
- 修改 S 的某个字符。
- 删除 S 的末尾字符。
我们需要计算最少需要多少次操作。
输入输出说明
- 输入:字符串 S 和 T。
- 输出:最少需要的操作次数。
关键点分析
- 找到 S 和 T 的最长公共前缀长度 commonLength。
- S 剩余部分需要删除,长度为 S.length−commonLength。
- T 剩余部分需要匹配修改,长度为 T.length−commonLength。
- 总操作次数 = S 删除次数 + T 修改次数。
二、解题思路
-
公共前缀匹配
遍历 S 和 T,从左到右逐字符比较,找到最长公共前缀长度 commonLength。 -
操作计算
- 从 S 中删除 S.length−commonLength 个字符。
- 修改 T.length−commonLength 个字符以匹配。
-
边界情况处理
- 如果 S 是 T 的前缀,直接返回 0。
- 如果 T 的前缀与 S 完全无关,返回 S.lengthS.length+T.length。
三、代码实现
import java.util.Arrays;
public class Main {
public static int solution(String S, String T) {
int minOperations = 0;
int minLength = Math.min(S.length(), T.length());
int commonLength = 0;
// 寻找公共前缀
for (int i = 0; i < minLength; i++) {
if (S.charAt(i) == T.charAt(i)) {
commonLength++;
} else {
break;
}
}
// 计算操作次数
minOperations = (S.length() - commonLength) + (T.length() - commonLength);
return minOperations;
}
public static void main(String[] args) {
System.out.println(solution("aba", "abb") == 1);
System.out.println(solution("abcd", "efg") == 4);
System.out.println(solution("xyz", "xy") == 1);
System.out.println(solution("hello", "helloworld") == 0);
System.out.println(solution("same", "same") == 0);
}
}
四、知识总结
-
字符串操作相关知识
- 公共前缀问题可以通过双指针或循环比较高效解决。
- 操作复杂度主要受字符串长度 O(min(S.length,T.length)) 影响。
-
优化方向
- 对于较长字符串,若前缀不同,直接返回最大可能的操作次数:S.length + T.length。
- 对于较短字符串,避免多余的字符比较。
-
编码风格
- 变量命名需清晰,如
commonLength明确含义,便于后续维护。 - 主函数中测试用例的简单断言
==检查,有助于快速验证功能。
- 变量命名需清晰,如
五、学习建议
-
刷题方法
- 先理解题意,分解问题。对常见问题如公共前缀、字符串匹配熟练掌握基础解法。
- 用手动推导验证小样例,确保思路正确。
-
错题利用
- 记录错题的输入输出及原因,分析错误点是边界问题还是逻辑遗漏。
- 再次练习时增加覆盖场景的测试样例。
-
结合工具
- 利用 MarsCode AI 提供的代码练习平台,快速验证思路,获得优化建议。
- 同时参考其他人的解法,比较优劣。
六、个人思考
在解决这道题时,最大的难点是边界处理,尤其是字符串长度差距较大的情况。例如 S 和 T 完全无关时,初步思路容易忽略直接返回最大操作数的优化方向。这提示我们,在刷题时,除了标准解法外,还应关注优化的可能性。
对于初学者,我建议从基础问题如最长公共前缀问题入手,逐步深入。结合豆包等AI辅助工具,能更高效地解决问题并优化思路。