【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 ...
随机推荐
- VTA:深度学习加速器堆栈
VTA:深度学习加速器堆栈 多功能Tensor加速器(VTA)是一个开放的,通用的,可定制的深度学习加速器,具有完整的基于TVM的编译器堆栈.设计VTA来展示主流深度学习加速器的最显着和共同的特征.T ...
- 深入理解java虚拟机笔记Chapter7
虚拟机类的加载机制 概述 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类的加载机制. 类加载的时机 J ...
- iis配置代理服务器解决跨域问题
iis配置代理服务器解决跨域问题 解决:在发布的项目根目录添加web.config配置文件 在配置文件中system.webServer节点中加入 <?xml version="1.0 ...
- Pandas高级教程之:处理缺失数据
目录 简介 NaN的例子 整数类型的缺失值 Datetimes 类型的缺失值 None 和 np.nan 的转换 缺失值的计算 使用fillna填充NaN数据 使用dropna删除包含NA的数据 插值 ...
- .NET Worker Service 部署到 Linux 作为 Systemd Service 运行
上一篇文章我们了解了如何将.NET Worker Service 作为 Windows 服务运行,今天我接着介绍一下如何将 Worker Service 部署到 Linux 上,并作为 Systemd ...
- gRPC(2):四种基本通信模式
在 gRPC(1):入门及简单使用(go) 中,我们实现了一个简单的 gRPC 应用程序,其中双方通信是简单的请求-响应模式,没发出一个请求都会得到一个响应,然而,借助 gRPC 可以实现不同的通信模 ...
- Linux-远程服务ssh
1.远程管理服务介绍 (1)SSH是(Secure Shell Protocol)的简写,由IETF网络工作小组制定:在进行数据传输之前,SSH先对联机数据包通过加密技术进行机密处理,加密后在进行文件 ...
- 跟我一起学 Go 系列:gRPC 拦截器
Go gRPC 学习系列: 跟我一起学Go系列:gRPC 入门必备 第一篇内容我们已经基本了解到 gRPC 如何使用 .对应的三种流模式.现在已经可以让服务端和客户端互相发送消息.本篇仍然讲解功能性的 ...
- 通过xrdp连接centos7桌面:
6.1.需求场景: 1.希望使用windows远程访问centos图形界面,使用xmanager连接centos远程桌面时有以下问题: (1)只能有一个用户同时使用xmanger连接远程桌面,多个用户 ...
- 在FLEX中真正的隐藏一个组件,隐藏后不占据自身的位置. (转)
一直被这个问题困扰,就是在设置UI的Visible的时候,改组件的位置一直被占着,比较恶心,今天在这里发现了一个方法, 操作方法如下设置: includeInLayout为false即可 来自:htt ...