什么是滑动窗口
- 在尽可能一次遍历中,在源串中找出目标串的匹配模式。
五道题目七种解法
更多更全面的算法题,尽在:算法和数据结构的Java实践
本文所有源码:slidingWindow 和 测试案例
正文开始
1、序列匹配
- 给定一个源字符串,再给一个目标字符串,看看源串中是否存在目标字符串的序列,比如:
- 正案例
- 源字符串:“1a2b3c4d”,
- 目标字符串:“1234”
- 很明显,源串中存在目标字符串的序列。
- 反案例:
- 源字符串:“1a2b3cd”,
- 目标字符串:“1234”
- 很明显,源串中不存在目标字符串的序列。
- 解法:因为我们的目的很简单,你只需要告诉我,存不存在,true or false,因此通过一次循环,source指针指向源串的位置,target指针指向目标串的位置,双指针同步工作,最后判断target指针是否等于目标串的长度即可,当然,这道题如果改成两者最长公共部分的序列,需要使用LCS的解法来处理,本题完整源码:SequenceExist。除了这种方法外,还有一个叫做字符串预处理的方法:字符串预处理法解决字符串匹配问题
- 主要代码:
- 正案例
while (sourcelength < source.length() && targetlength < target.length()){
if(targetchar[targetlength] == sourcechar[sourcelength]){
targetlength++;
}
sourcelength++;
}
return targetlength == target.length();
2、最小覆盖子串
- 接着上一题思考:如果源字符串中存在多个序列匹配目标字符串,如何找出长度最小的那个子串?
- 给定一个源字符串,再给一个目标字符串,看看源串中是否存在目标字符串的序列,特别的是:对于这个序列,我们允许它在源字符串中乱序存在。但是如果仅仅是存在性判断,那么一个list或者hashmap完全可以搞定,将目标字符串存入list中,遍历源字符串,从list中删除这个字符,什么时候list空了,return true,否则reture false。
- 我们要求更进一步,假设存在多个目标字符串的字符存在于源字符串中,那么找出包含目标字符串中所有字符的最小区间,比如:
- 正案例
- 源字符串:“2a41b156d3c24d”,
- 目标字符串:“1234”
- 很明显,源串中乱序存在目标字符串的序列,但是这其中最小的覆盖子串的区间是“156d3c24”。
- 反案例:
- 源字符串:“1a2b3cd”,
- 目标字符串:“1234”
- 很明显,源串中根本不存在目标字符串的序列。
- 解法:这道题需要从滑动窗口的角度来考虑,完整源码:
- 正案例