28.找出第一个匹配项下标
题目链接:28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)
初始代码: 暴力解法,时间复杂度为m*n,代码繁琐。
class Solution {
public int strStr(String haystack, String needle) {
int hlen=haystack.length();
int nlen=needle.length();
if(hlen<nlen)return -1;
if(hlen==nlen){
if(compare(haystack,needle)){
return 0;
}
}
for(int i=0;i<=hlen-nlen;i++){
String sub=haystack.substring(i,i+nlen);
if(compare(sub,needle)){
return i;
}
}
return -1;
}
public boolean compare(String s,String needle){
int n=s.length();
int hi=0;
int ni=0;
while(hi<n){
if(s.charAt(hi)!=needle.charAt(ni)){
return false;
}
hi++;
ni++;
}
return true;
}
}
官方解法:
class Solution {
public int strStr(String haystack, String needle) {
int n=haystack.length(),m=needle.length();
for(int i=0;i+m<=n;i++){
boolean flag=true;
for(int j=0;j<m;j++){
if(haystack.charAt(i+j)!=needle.charAt(j)){
flag=false;
break;
}
}
if(flag){
return i;
}
}
return -1;
}
}
对比不同:1.可以引入标识flag。2.双重循环直接对比,i+j来表示下标
KMP算法:为了解决一个字符串包不包含另一个字符串的问题
视频讲解:帮你把KMP算法学个通透!(求next数组代码篇)_哔哩哔哩_bilibili
class Solution {
public int strStr(String haystack, String needle) {
//方法二:KMP算法,时间复杂度为n+m,空间复杂度为m
int n=haystack.length();
int m=needle.length();
if(m==0){
return 0;
}
//定义最大相等前后缀数组next
int[] next=new int[m];
//计算初始数组,即needle的最大相等前后缀数组,i表示后缀末尾,j表示前缀末尾
for(int i=1,j=0;i<m;i++){
//不相等的情况,j回到数组上一位
while(j>0&&needle.charAt(i)!=needle.charAt(j)){
j=next[j-1];
}
//相等情况,j++;
if(needle.charAt(i)==needle.charAt(j)){
j++;
}
//此时j就是i的最大前后缀所在位置。
next[i]=j;
}
//对两个字符串进行比较,和上一步类似。
for(int i=0,j=0;i<n;i++){
while(j>0&&haystack.charAt(i)!=needle.charAt(j)){
j=next[j-1];
}
if(haystack.charAt(i)==needle.charAt(j)){
j++;
}
if(j==m){
return i-m+1;
}
}
return -1;
}
}
459重复子字符串
题目链接:459. 重复的子字符串 - 力扣(LeetCode)
视频讲解:字符串这么玩,可有点难度! | LeetCode:459.重复的子字符串_哔哩哔哩_bilibili
class Solution {
public boolean repeatedSubstringPattern(String s) {
//方法一:暴力解法
int n=s.length();
//i代表重复子串的长度
for(int i=1;i<=s.length()/2;i++){
if(n%i==0){
boolean match=true;
for(int j=i;j<n;j++){
if(s.charAt(j)!=s.charAt(j-i)){
match=false;
break;
}
}
if(match){
return true;
}
}
}
return false;
}
}
class Solution {
public boolean repeatedSubstringPattern(String s) {
return (s+s).indexOf(s,1)!=s.length();
}
}
class Solution {
public boolean repeatedSubstringPattern(String s) {
//方法三:运用KMP算法
if(s.equals(""))return false;
int len=s.length();
s=" "+s;
char[] ch=s.toCharArray();
int[] next=new int[len+1];
for(int i=2,j=0;i<=len;i++){
while(j>0&&ch[i]!=ch[j+1])j=next[j];
if(ch[i]==ch[j+1]){
j++;
}
next[i]=j;
}
if(next[len]>0&&len%(len-next[len])==0){
return true;
}
return false;
}
}