【LeetCode】28. 实现 strStr()
28. 实现 strStr()
知识点:字符串;KMP算法
题目描述
实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例
输入:haystack = "hello", needle = "ll"
输出:2
输入:haystack = "aaaaa", needle = "bba"
输出:-1
输入:haystack = "", needle = ""
输出:0
解法一:暴力法
直接对于haystack中的每一位,依次比较needle,如果发生不匹配了,则移动到haystack中的下一位;
class Solution {
public int strStr(String haystack, String needle) {
if(needle.length() == 0) return 0;
for(int i = 0; i <= haystack.length()-needle.length(); i++){ //注意判断条件;
int j = 0;
while(j < needle.length() && haystack.charAt(i+j) == needle.charAt(j)){
j++;
}
if(j == needle.length()) return i; //满足证明完全匹配上了;
}
return -1;
}
}
时间复杂度:O(NM);
解法二:KMP算法
可以查看KMP算法
KMP算法的本质上就是在利用先前的信息减少不可能的匹配,把不可能的匹配都直接过滤。而这个过滤的依据就是next数组,next数组里的数的含义是以此数结尾时,最多能用前面几个数来顶替掉我们后面几个数。
要清楚我们根据next数组去过滤是不可能漏掉情况的。为什么呢?比如说ababca,我到了最后一个a处匹配不上了,那按照上面的解法,现在应该看a处前一位也就是c的对应next值,很明显next[4]是0,所以模式串的指针就移动到最开始,也就等于将模式串的首位直接对齐到了主串中原本与a不匹配的那个位置,中间可能错过某些可能吗?比如说我最开始的ab可以移动到2,3位置处,那也是ab说不定可能呢,其实这是不可能的,为什么呢,反证法;如果0和1处的ab匹配上了2和3处的ab,那么后一个一定不匹配,因为如果匹配的话,那就是说前3个能匹配上后3个,那next[4]就等于3而不是0了,所以这也就说明了为什么我们是看前一个也就是看c的next值,因为无论怎样,我们都是要经过它的,如果不看它,那它前面几个匹配上了,到它也匹配不上;
class Solution {
public int strStr(String haystack, String needle) {
if(needle.length() == 0) return 0;
if(haystack.length() == 0) return -1;
char[] s = haystack.toCharArray();
char[] p = needle.toCharArray();
return KMP(s,p);
}
private int KMP(char[] s, char[] p){
int tar = 0; //主串中待匹配的位置;
int pos = 0; //模式串中待匹配的位置;
int m = s.length;
int n = p.length;
int[] next = next(p, n); //构建next数组;
while(tar < m){
if(s[tar] == p[pos]){ //匹配上就接着比下一个;
tar++;
pos++;
}else if(pos != 0){ //匹配不上了,而且pos指针还没移动到模式串最开始;
pos = next[pos-1]; //看匹配不上的前一位的next数组值;
}else{ //pos已经到模式串最开始了,而且会经过最开始的if,如果这也没匹配上,说明tar对应的值匹配不上,直接向后移一位;
tar++;
}
if(pos == n){ //pos到了模式串最后,全匹配上了;
return tar-n;
}
}
return -1;
}
private int[] next(char[] p, int n){
int[] next = new int[n];
int now = 0;
int i = 1;
while(i < n){
if(p[now] == p[i]){
now++;
next[i] = now;
i++;
}else if(now != 0){ //now没回到最开始呢;
now = next[now-1]; //使得A的K前缀等于B的K后缀的最大K;A和B又一样。所以就看A就可以了;
//看now前一位的最长前后缀;
}else{
next[i] = now; //移动到最开始了还不行,那就是0了;
i++;
}
}
return next;
}
}
时间复杂度:O(N)+O(M);
体会
要掌握字符串匹配,要掌握KMP算法,要经常看这篇文章:KMP算法
【LeetCode】28. 实现 strStr()的更多相关文章
- <每日 1 OJ> -LeetCode 28. 实现 strStr()
题目: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存 ...
- 前端与算法 leetcode 28.实现 strStr()
# 前端与算法 leetcode 28.实现 strStr() 题目描述 28.移除元素 概要 这道题的意义是实现一个api,不是调api,尽管很多时候api的速度比我们写的快(今天这个我们可以做到和 ...
- Java实现 LeetCode 28 实现strStr()
28. 实现 strStr() 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 ...
- 44. leetcode 28. Implement strStr()
28. Implement strStr() Implement strStr(). Returns the index of the first occurrence of needle in ha ...
- [LeetCode] 28. Implement strStr() 实现strStr()函数
Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle ...
- LeetCode 28 Implement strStr() (实现找子串函数)
题目链接: https://leetcode.com/problems/implement-strstr/?tab=Description Problem : 实现找子串的操作:如果没有找到则返回 ...
- Leetcode #28. Implement strStr()
Brute Force算法,时间复杂度 O(mn) def strStr(haystack, needle): m = len(haystack) n = len(needle) if n == 0: ...
- Java [leetcode 28]Implement strStr()
题目描述: Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if ...
- [LeetCode] 28. Implement strStr() 解题思路
Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...
- Leetcode 28——Implement strStr()
Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle ...
随机推荐
- TensorFlow csv读取文件数据(代码实现)
TensorFlow csv读取文件数据(代码实现) 大多数人了解 Pandas 及其在处理大数据文件方面的实用性.TensorFlow 提供了读取这种文件的方法. 前面章节中,介绍了如何在 Tens ...
- 什么是视觉Visual SLAM
什么是视觉Visual SLAM What Is Visual SLAM? What are the origins of visual SLAM? and what are some other a ...
- 72 个网络应用安全实操要点,全方位保护 Web 应用的安全
原文地址:Web Application Security Checklist 原文作者:Teo Selenius(已授权) 译者 & 校正:HelloGitHub-小熊熊 & 卤蛋 ...
- Markdown个人常用语法
Markdown实用格式 标题 # 标题一级 ## 标题二级 ### 标题三级 #### 标题四级 ##### 标题五级 ###### 标题六级 粗体.斜体和删除线 **加粗字体** *斜体字体* * ...
- Centos acme.sh 申请 LetsEncrypt 通配证书
1. 安装 acme.sh 注意:如果需要使用 Standalone Mode请先安装socat# yum intall socat It is recommended to install soca ...
- 【NX二次开发】Block UI 选择表达式
属性说明 属性 类型 描述 常规 BlockID String 控件ID Enable Logical 是否可操作 Group ...
- 【VBA】excel自动换名字打印
源码: Sub m() For i = 1 To 100 ActiveSheet.PrintOut copies:=1 Cells(1, 1) = Sheets(2).Cells(i, 1) Next ...
- 【C++】Vector求最大值最小值
最大值: int max = *max_element(v.begin(),v.end()); 最小值: int min = *min_element(v.begin(),v.end());
- 如何提升springboot服务吞吐量
生产环境偶尔会有一些慢请求导致系统性能下降,吞吐量下降,下面介绍几种优化建议. 方案 1.undertow替换tomcat 电子商务类型网站大多都是短请求,一般响应时间都在100ms,这时可以将web ...
- 解决 Golnag Gin框架跨域
package main import ( "github.com/gin-gonic/gin" "awesomeProject/app/app_routers" ...