【LeetCode】字符串匹配
给定目标串 haystack 和模式串 needle ,返回 needle 在 haystack 中第一次出现的位置下标,若 needle 不是 haystack 的子串则返回 -1。
1. Brute-Force Algorithm(暴力算法 / 简单模式匹配)
我自己写了一种双层循环的
int strStr(string haystack, string needle) {
if (needle.empty()) return ;
int m = haystack.size(), n = needle.size();
for (int i = ; i <= m - n; i++) {
for (int j = ; j < n; j++) {
if (needle[j] != haystack[i + j])
break;
if (j == n - )
return i;
}
}
return -;
}
看了答案发现了一种更高效的方法,虽然时间复杂度同样是 O(m*n),但只要一层循环,非常Nice!
int strStr(string haystack, string needle) {
if (needle.empty()) return ;
int i = , j = ;
int m = haystack.size(), n = needle.size();
while (i < m && j < n) {
if (haystack[i] == needle[j]) {
i++;
j++;
} else {
i = i - j + ;
j = ;
}
if (j == n)
return i - j;
}
return -;
}
2. KMP算法
算法讲解可以参考 http://www.61mon.com/index.php/archives/183/ ,讲解的已经很好了。
KMP的时间复杂度仅为 O(m+n),因为当出现子串与主串某处不匹配时,并不会将遍历主串的下标 i 回溯,而是利用得到的 next 数组将模式子串向右“滑动”尽可能远的一段距离,继续进行比较,提高了效率。
next 数组的求解是关键,它是基于模式子串的最长前后缀,next[i] = needle[0] 到 needle[i - 1] 的字符串的最长相同前后缀的长度。
void getNext(string needle, vector<int> &next) {
int i = , j = -;
// j 表示最长相同前后缀的长度
next[] = j;
while (i < needle.size()) {
// j == -1 为边界条件判断, j = next[j] 可能使 j 退回到 -1
if (j == - || needle[i] == needle[j]) {
i++;
j++;
next[i] = j;
} else {
j = next[j];
}
}
}
int strStr(string haystack, string needle) {
if (needle.empty()) return ;
int i = , j = ;
int m = haystack.size(), n = needle.size();
vector<int> next(n + );
getNext(needle, next);
while (i < m && j < n) {
if (j == - || haystack[i] == needle[j]) {
i++;
j++;
} else {
j = next[j];
}
if (j == n)
return i - j;
}
return -;
}
改进的KMP算法
void getNextval(string needle, vector<int> &nextval) {
int i = , j = -;
nextval[] = j;
while (i < needle.size()) {
if (j == - || needle[i] == needle[j]) {
i++;
j++;
// 生成 nextval 数组
if (needle[i] != needle[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
} else {
j = nextval[j];
}
}
}
int strStr(string haystack, string needle) {
if (needle.empty()) return ;
int i = , j = ;
int m = haystack.size(), n = needle.size();
vector<int> nextval(n + );
getNextval(needle, nextval);
while (i < m && j < n) {
if (j == - || haystack[i] == needle[j]) {
i++;
j++;
} else {
j = nextval[j];
}
if (j == n)
return i - j;
}
return -;
}
【LeetCode】字符串匹配的更多相关文章
- 滑动窗口通用解leetcode字符串匹配问题
滑动窗口,这玩意解决一些字符串匹配的题目是真的挺好用的,虽然本质还是双指针. 思路: 1.维护一个窗口,不断的向右边移动 2.满足要求后,移动左边,当不满足时,跳出. 3.重复1,2.得出答案. 下面 ...
- LeetCode 44 Wildcard Matching(字符串匹配问题)
题目链接:https://leetcode.com/problems/wildcard-matching/?tab=Description '?' Matches any single chara ...
- LeetCode 10 Regular Expression Matching(字符串匹配)
题目链接 https://leetcode.com/problems/regular-expression-matching/?tab=Description '.' Matches any si ...
- leetcode笔记 动态规划在字符串匹配中的应用
目录 leetcode笔记 动态规划在字符串匹配中的应用 0 参考文献 1. [10. Regular Expression Matching] 1.1 题目 1.2 思路 && 解题 ...
- LeetCode 942. 增减字符串匹配(DI String Match) 49
942. 增减字符串匹配 942. DI String Match 题目描述 每日一算法2019/6/21Day 49LeetCode942. DI String Match Java 实现 and ...
- LeetCode 686. 重复叠加字符串匹配(Repeated String Match)
686. 重复叠加字符串匹配 686. Repeated String Match 题目描述 给定两个字符串 A 和 B,寻找重复叠加字符串 A 的最小次数,使得字符串 B 成为叠加后的字符串 A 的 ...
- Leetcode 686.重复叠加字符串匹配
重复叠加字符串匹配 给定两个字符串 A 和 B, 寻找重复叠加字符串A的最小次数,使得字符串B成为叠加后的字符串A的子串,如果不存在则返回 -1. 举个例子,A = "abcd", ...
- Java实现 LeetCode 686 重复叠加字符串匹配
686. 重复叠加字符串匹配 给定两个字符串 A 和 B, 寻找重复叠加字符串A的最小次数,使得字符串B成为叠加后的字符串A的子串,如果不存在则返回 -1. 举个例子,A = "abcd&q ...
- 字符串匹配KMP算法详解
1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...
- 快速字符串匹配一: 看毛片算法(KMP)
前言 由于需要做一个快速匹配敏感关键词的服务,为了提供一个高效,准确,低能耗的关键词匹配服务,我进行了漫长的探索.这里把过程记录成系列博客,供大家参考. 在一开始,接收到快速敏感词匹配时,我就想到了 ...
随机推荐
- 最简单的服务器和客户机(python3的编码与解码问题)
在学习python的过程中,我越来越感觉到python2和python3之间有很多不同点,最近发现的一点就是编码问题. 在代码清单14-1和14-2中,因为作者是用python2来写得,然后我是用py ...
- CSS基本内容
CSS样式表的三种引入方式: 1.外部样式表——即将CSS样式写在单独的一个.css文件中: <link rel="stylesheet" type="text/c ...
- MyBatis数据库测试代码自动生成
<!-- generatorConfig.xml配置,其中:<plugin type="org.mybatis.generator.plugins.ToStringPlugin& ...
- React Native 组建之IOS和Android通用抽屉
/** * Sample React Native App * https://github.com/facebook/react-native * @flow *npm:https://www.np ...
- P1547 Out of Hay
传送门 练习 只是一个最小生成树的水题,拿来练练模板 AC代码: #include<iostream> #include<cstdio> #include<alg ...
- CentOS7 安装Perl
官网:http://www.cpan.org/src/ wget https:.tar.gz cd perl- ./Configure -des -Dprefix=$HOME/localperl ma ...
- springboot + mybatis 的项目,实现简单的CRUD
以前都是用Springboot+jdbcTemplate实现CRUD 但是趋势是用mybatis,今天稍微修改,创建springboot + mybatis 的项目,实现简单的CRUD 上图是项目的 ...
- 关于repaint和reflow的笔记
repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,box-shadow不 ...
- js几个小技巧和坑
蝴蝶书看了,也知道充满了毒瘤和糟粕,但该用还是得用. 实际写了几天,小技巧记录下来.都是在py里有直接答案,不会遇到的问题,没想到js里这么费事. 还是要多读<ES6标准入门> 1判断ob ...
- MySQL学习(十三)
编码问题 乱码是如何形成的 1 解码时与实际编码不一致 可修复 2 传输过程中,编码不一致,导致字节丢失,不可修复,如把utf8转为GB2312 连接器的特性:连接客户端和服务器,客户端的字符先发给连 ...