公司动态
双指针算法解决LeetCode长按键入问题
1. 问题背景与需求分析长按键入是LeetCode上经典的字符串处理问题编号925。题目描述为你的朋友正在使用键盘输入名字name偶尔在键入字符时会长时间按下某个键导致字符可能被重复输入一次或多次。我们需要检查键入的字符串typed是否是name字符串经过长按键入后得到的合法结果。这个问题的实际应用场景非常广泛手机键盘输入时的误触检测密码输入时的重复字符校验语音识别中的持续音处理硬件键盘的防抖检测2. 双指针解法核心思路2.1 算法设计原理双指针法之所以适合解决这个问题是因为我们需要同时遍历两个字符串比较它们的字符是否匹配同时处理可能的重复字符。具体来说初始化两个指针i和j分别指向name和typed的开头逐个比较字符如果字符匹配两个指针都前进如果不匹配检查typed当前字符是否是name前一个字符的重复最终检查是否两个指针都到达了各自字符串的末尾这种解法的时间复杂度是O(nm)空间复杂度是O(1)是最优解。2.2 边界条件处理在实际编码中需要特别注意以下边界情况name为空字符串时typed也必须为空typed比name短时直接返回false开头字符不匹配时直接返回false连续重复字符的数量typed必须≥name中的数量3. 完整代码实现与解析3.1 Python实现示例def isLongPressedName(name: str, typed: str) - bool: i j 0 while j len(typed): if i len(name) and name[i] typed[j]: i 1 j 1 elif j 0 and typed[j] typed[j-1]: j 1 else: return False return i len(name)3.2 关键代码解读双指针初始化i和j分别追踪name和typed的位置主循环条件只要typed还有字符就继续处理第一个if字符匹配时的处理elif处理合法重复字符的情况else遇到非法字符直接返回false最终检查name的所有字符必须都被匹配4. 测试用例设计4.1 常规测试用例assert isLongPressedName(alex, aaleex) True # 基本通过案例 assert isLongPressedName(saeed, ssaaedd) False # e被a打断 assert isLongPressedName(leelee, lleeelee) True # 多组重复4.2 边界测试用例assert isLongPressedName(, ) True # 双空 assert isLongPressedName(a, b) False # 完全不匹配 assert isLongPressedName(pypl, ppyypll) True # 混合重复 assert isLongPressedName(alex, alexxr) False # 结尾多余字符5. 算法优化与变种5.1 性能优化技巧虽然双指针已经是O(n)解法但还可以进行微优化添加长度提前判断if len(typed) len(name): return False使用for循环代替while可以减少变量声明在比较字符时使用直接内存访问而非索引操作5.2 问题变种思考这个问题可以有多种变体适合面试扩展允许最多k次错误的长按键入统计name中每个字符的最小和最大重复次数找出typed中所有可能对应的name处理退格键情况的字符串比较6. 实际工程应用6.1 输入法纠错系统在手机输入法中可以应用类似算法处理用户连续输入相同字符时的自动校正滑动输入时的冗余字符过滤九宫格输入时的长按数字处理6.2 日志分析场景在服务器日志分析中可能遇到重复的请求记录检测是否是正常的重试机制区分恶意重复请求和正常操作压缩重复的日志条目7. 常见错误与调试技巧7.1 典型错误模式指针越界忘记检查i len(name)导致索引错误初始条件遗漏没有处理空字符串情况顺序错误先检查重复再检查匹配会导致逻辑错误终止条件错误只检查了j len(typed)而忘记检查i7.2 Debugging方法打印指针位置和当前字符print(fi{i}, j{j}, name[i]{name[i]}, typed[j]{typed[j]})可视化两个字符串的比对过程使用小规模测试用例逐步验证画状态转移图理清逻辑8. 扩展学习建议类似的双指针题目判断子序列LeetCode 392合并两个有序数组LeetCode 88盛最多水的容器LeetCode 11字符串处理进阶正则表达式匹配编辑距离计算KMP算法系统设计中的应用文件diff工具的实现版本控制系统中的冲突检测生物信息学中的序列比对