【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)
前言 由于需要做一个快速匹配敏感关键词的服务,为了提供一个高效,准确,低能耗的关键词匹配服务,我进行了漫长的探索.这里把过程记录成系列博客,供大家参考. 在一开始,接收到快速敏感词匹配时,我就想到了 ...
随机推荐
- vue.js精讲01
笔记及源码地址 : https://github.com/wll8/vue_note 01 2017-09-13 view一个 mvvm框架(库),和 ag 类似.比较小巧,容易上手. mvc: mv ...
- shell案例题
目录: 1.批量生成随机字符文件名案例 2.批量改名特殊案例 3.批量创建特殊要求用户案例 1.批量生成随机字符文件名案例(P359) (1).利用openssl命令来实现 #!/bin/bash # ...
- C语言: 从 CodeBlocks 到 Microsoft Visual Studio 2017
开学到现在寒假,学习了一个学期的C语言,同时也已然用了大半年的 CodeBlocks 来写 C/C++ 程序.CodeBlocks 是写 C/C++ 语言的程序最轻量的IDE(集成开发环境),在 C ...
- java web 工程更改名字
如图: 将工程名字struts2Project02更改为struts2Project03,步骤如下: 1. 右键工程名字,选中properties,如图 2.更改项目名字 3.第2步已经真正把项目名字 ...
- React Naive 解决防止多次点击的解决方法
export default class TouchableOpacity extends Component { render() { return ( <TouchableOpacity a ...
- dml语句和ddl语句 区别
delete from user删除所有记录,属于dml语句,一条记录一条记录删除.事务可以作用在dml语句上的 truncate table user;删除所有记录,属于ddl语句,将表删除,然后重 ...
- [osg]osgcallback各种回调使用的例子介绍
观察MyReadFileCallback结构体的内容,可以发现它继承自osgDB::Registry::ReadFileCallback,并重载了一个函数readNode,分析源代码可知,该函数在os ...
- web 常用颜色
1. 推荐链接 RGB颜色值与十六进制颜色码转换工具 Web上16种基本颜色名称 WEB标准颜色 2. 个人常用 除了三原色,还有 #daf1ef#4DBCB0#ccc
- JNI C创建Java字符串数组
创建Java字符串数组 注:jni中没有与String[]对应的数据类型,所以需要创建对象数组,循环添加jstring对象 #include <Sample3.h> #include &l ...
- ssh REMOTE HOST IDENTIFICATION HAS CHANGED!
连接到docker的时候,有时因为image重新buid过,就提示 It is also possible that a host key has just been changed. 不让连接. 解 ...