图解 Java 滑动窗口:「最长公共前缀的匹配长度」的窗口比较法
·
图解 Java 滑动窗口:「最长公共前缀的匹配长度」的窗口比较法
问题背景
在字符串处理中,最长公共前缀匹配是常见问题,即从两个字符串的起始位置找出最大连续相同字符序列。例如:
- 字符串 $A$:
"algorithm" - 字符串 $B$:
"alpine" - 最长公共前缀:
"al"(长度=2)
传统暴力解法需 $O(n \times m)$ 时间复杂度。本文将详解基于滑动窗口的优化方案,通过动态调整窗口边界实现高效匹配。
算法核心思想
-
窗口初始化
设双指针 $[left, right]$ 表示当前匹配窗口:- $left$ 固定为字符串 $A$ 和 $B$ 的起始位置
- $right$ 从 $0$ 开始向右扩展 $$ \text{初始化:} left=0,\ right=0 $$
-
窗口滑动规则
- 当 $A[right] = B[right]$ 时:
- 匹配成功,$right$ 右移扩大窗口
- 更新最大匹配长度 $max\_len = \max(max\_len,\ right-left)$
- 当 $A[right] \neq B[right]$ 时:
- 匹配失败,终止当前窗口
- 重置 $right = left$(窗口收缩至起点)
- 当 $A[right] = B[right]$ 时:
-
终止条件
任一字符串遍历完成即终止: $$ \text{终止条件:} right \geq \min(len(A),\ len(B)) $$
动态演示
以 $A = \text{"flower"},\ B = \text{"flow"}$ 为例:
| 步骤 | $left$ | $right$ | 窗口内容 | 匹配状态 | $max\_len$ |
|---|---|---|---|---|---|
| 1 | 0 | 0 | "f" vs "f" |
✅ | 1 |
| 2 | 0 | 1 | "fl" vs "fl" |
✅ | 2 |
| 3 | 0 | 2 | "flo" vs "flo" |
✅ | 3 |
| 4 | 0 | 3 | "flow" vs "flow" |
✅ | 4 |
最终结果:最长公共前缀长度 $=4$("flow")
Java 代码实现
public class LongestCommonPrefix {
public static int findMaxPrefixLength(String s1, String s2) {
if (s1 == null || s2 == null) return 0;
int left = 0, right = 0;
int maxLen = 0;
while (right < s1.length() && right < s2.length()) {
if (s1.charAt(right) == s2.charAt(right)) {
maxLen = Math.max(maxLen, right - left + 1);
right++; // 扩大窗口
} else {
break; // 终止匹配
}
}
return maxLen;
}
public static void main(String[] args) {
String A = "database";
String B = "dataflow";
System.out.println("最长公共前缀长度:" + findMaxPrefixLength(A, B)); // 输出:4 ("data")
}
}
算法分析
-
时间复杂度
仅需单次遍历:$O(\min(n,m))$
($n,\ m$ 为两字符串长度) -
空间复杂度
仅用常量指针:$O(1)$ -
优势
- 无需预处理字符串
- 窗口边界移动实现高效匹配
- 适应实时数据流场景
应用场景
- 路由路径匹配
在Web框架中快速匹配URL前缀(如Spring MVC) - 基因序列比对
生物信息学中DNA碱基序列的初始段匹配 - 版本控制
检测软件版本号的兼容性前缀(如"v1.2.3"与"v1.3.0")
总结
滑动窗口法通过动态调整边界,将最长公共前缀匹配优化至线性时间复杂度。核心在于:
- 利用指针 $right$ 的单向移动特性
- 通过字符比对实时控制窗口伸缩
- 以最小代价获取最大匹配信息
该方法兼具高效性与简洁性,是字符串处理的经典实践。
更多推荐


所有评论(0)