目录
Leetcode28 实现strStr()
实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = "hello", needle = "ll"
输出:2
示例 2:
输入:haystack = "aaaaa", needle = "bba"
输出:-1
示例 3:
输入:haystack = "", needle = ""
输出:0
参考:帮你把KMP算法学个通透!(求next数组代码篇)_哔哩哔哩_bilibili
基础知识
前缀
包含第一个字符,不包含最后一个字符的连续字母
后缀
包含最后一个字符,不包含第一个字符的连续字母
前缀表
保存 最长相等前后缀的长度
ex aabaa 最长相等前后缀长度为2
KMP
跳到前一个前缀表位置存储的下标位置
构建前缀表过程
两个下标
i:后缀的末尾位置 j:前缀的末尾位置&&长度信息
// 构建前缀表
for(int i=1,j=0;i<m;){
// 找到匹配位置
while(j>0&&p[i]!=p[j]){
j=next[j-1];
}
// 相同长度++
if(p[i]==p[j]){
j++;
}
// 更新前缀表
next[i]=j;
i++;
}
总代码
class Solution {
public int strStr(String ss, String pp) {
char[] s=ss.toCharArray(),p=pp.toCharArray();
int n=s.length,m=p.length;
if(m==0)return 0;
int[] next=new int[m];
// 构建前缀表
for(int i=1,j=0;i<m;){
// 找到匹配位置
while(j>0&&p[i]!=p[j]){
j=next[j-1];
}
// 相同长度++
if(p[i]==p[j]){
j++;
}
// 更新前缀表
next[i]=j;
i++;
}
// 使用前缀表
for(int i=0,j=0;i<n;i++){
// 匹配串更新匹配位置
while(j>0&&s[i]!=p[j]){
j=next[j-1];
}
// 相同则双方++
if(s[i]==p[j]){
j++;
}
// 匹配到末尾了直接返回
if(j==m){
return i-m+1;
}
}
return -1;
}
}
给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
练习 459. 重复的子字符串
示例 1:
输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba"
输出: false
示例 3:
输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
class Solution {
public boolean repeatedSubstringPattern(String s) {
char[] cs = s.toCharArray();
int n = cs.length;
int[] next = new int[n];
// 构建前缀表
for(int i=1,j=0;i<n;i++){
while(j>0&&cs[i]!=cs[j]){
j=next[j-1];
}
if(cs[i]==cs[j]){
j++;
}
next[i] = j;
}
// 字符串长度是相同前后缀长度的倍数时返回true
return next[n-1]!=0&&(n%next[n-1]==0);
}
}