一、暴力比较字符串时间复杂度为0(N*M)
/**
* 暴力匹配 时间复杂度为 O(N*M)
* @param str1
* @param str2
* @return
*/
public static boolean compareString(String str1, String str2) {
int n = str1.length();
int m = str2.length();
char[] str1Arr = str1.toCharArray();
char[] str2Arr = str2.toCharArray();
if(n < m) {
return false;
}
//i是str1的指针 j是str2的指针
for(int i = 0; i < n; i++) {
if(i + m > n) {
return false;
}
int count = 0;
for (int j = 0; j < m ; j++) {
int k = i+j;
if(str1Arr[k] == str2Arr[j]) {
count++;
continue;
} else {
count = 0;
break;
}
}
if(count == m) {
return true;
}
}
return false;
}
二、基于KMP算法时间时间复杂度O(N+M)
/**
* 获取比较字符串的 next数组 next数据表示字符串每个字符的前缀字符串与后缀字符串相等时的最大值
* @param str
* @return
*/
public static int[] next(String str) {
if(str.length() == 1) {
return new int[]{-1};
}
char[] strArr = str.toCharArray();
//声明next数组 长度为源字符串的长度
int[] next = new int[str.length()];
next[0] = -1;
next[1] = 0;
//i为next数据的索引
int i = 2;
//cn为上一个相等前缀字符串的长度
int cn = 0;
while (i < next.length) {
if(strArr[i-1] == strArr[cn]) {
next[i++] = ++cn;
} else if(cn > 0) {
cn = next[cn];
} else {
next[i++] = 0;
}
}
return next;
}
/**
* 基于kmp算法 比较两个字符串 返回比较字符串
* @param str1
* @param str2
* @return
*/
public static int compareStringByKMP(String str1, String str2) {
int str1Length = str1.length();
int str2Length = str2.length();
char[] str1Arr = str1.toCharArray();
char[] str2Arr = str2.toCharArray();
int[] next = next(str2);
int str1Index = 0;
int str2Index = 0;
while(str1Index < str1Length && str2Index < str2Length) {
if(str1Arr[str1Index] == str2Arr[str2Index]) {
str1Index++;
str2Index++;
} else {
if(next[str2Index] == -1) {
str1Index++;
} else {
str2Index = next[str2Index];
}
}
}
return str2Index == str2Length ? str1Index - str2Index : -1;
}
三、扩展-基于KMP实现二叉树判断子树
我们给两个二叉树,然后将每个二叉树序列化,可以前中后随意。将序列化后的字符串进行按照kmp算法进行比较。