1.题目

https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/
leetcode 28
字符串匹配之BF(Brute Force)算法是一种简单的字符串匹配算法,也叫暴力匹配算法。它的思想是将目标串 S 的第一个字符与模式串 T 的第一个字符进行匹配,如果相等,就继续比较 S 的第二个字符和 T 的第二个字符,如果不相等,就比较 S 的第二个字符和 T 的第一个字符,依次比较下去,直到找到一个匹配或者遍历完整个目标串
这个算法的时间复杂度是 O(mn) ,其中 m 和 n 是目标串和模式串的长度。空间复杂度是 O(1) ,因为不需要额外的空间
BF算法的优点是
简单易懂,实现起来不复杂,适用于短字符串的匹配。
BF算法的缺点是
效率较低,每次匹配失败时都要回溯主串和模式串的指针,导致大量的重复比较,时间复杂度为 O(nm) ,其中 n 是主串的长度,m 是模式串的长度。
2.解法
解法一:双指针,一个字符一个字符比较
这个实现的思想是定义一个指针 i 指向目标串 S 的当前位置,定义一个指针 j 指向模式串 T 的当前位置。每次比较 S[i] 和 T[j] ,如果相等,就让 i 和 j 都加一,继续比较下一个字符。如果不相等,就让 i 回退到上一次匹配的下一个位置,让 j 重置为 0 ,重新开始匹配。如果 i 超过了 S 的长度,或者 j 等于了 T 的长度,就结束循环。如果 j 等于了 T 的长度,说明找到了一个匹配,返回 i - j 作为匹配的起始位置。如果 i 超过了 S 的长度,说明没有找到匹配,返回 -1 作为标志。
public class StringBF {
public static void main(String[] args) {
String s = "leetcode";
String t = "tco";
System.out.println(bruteForce(s, t));
}
public static int bruteForce(String s, String t) {
int i = 0, j = 0;
while (i < s.length() && j < t.length()) {
if (s.charAt(i) == t.charAt(j)) {
i++;
j++;
} else {
i = i - j + 1;
j = 0;
}
}
if (j == t.length() ) {
return i - j;
}
return -1;
}
}
解法二:滑动窗口+ subString 整体比较
思路
BF算法在 JDK 中有一些应用,比如 String 类的 indexOf() 方法和 lastIndexOf() 方法,都是使用 BF 算法来实现的。这些方法可以用来查找一个字符串中是否包含另一个字符串,或者返回一个字符串在另一个字符串中的位置
BF算法,也就是暴力匹配算法。它的基本思想是,从haystack的第一个字符开始,依次与needle的每个字符进行比较,如果都相等,就返回当前的索引;如果有不相等的,就从haystack的下一个字符开始,重复这个过程,直到找到匹配的子字符串或者遍历完haystack为止。
代码逻辑
- 首先,检查haystack和needle是否为空,如果是,就返回-1,因为这是一个无效的输入。
- 其次,检查haystack和needle是否相等,如果是,就返回0,因为这意味着needle就是haystack的第一个子字符串。
- 然后,获取needle的长度,用它作为滑动窗口的大小。
- 接着,从左到右遍历haystack,每次取出一个长度为needleLength的子字符串,与needle进行比较。
- 如果相等,就返回当前的索引i,表示找到了needle在haystack中的第一个位置。
- 如果不相等,就继续向右滑动窗口,直到遍历完整个haystack或者找到匹配的子字符串为止。
- 最后,如果遍历完haystack都没有找到匹配的子字符串,就返回-1,表示needle不是haystack的一部分。
具体实现
public class ImplementStrStr {
public int strStr(String haystack, String needle) {
// 基本条件
if (haystack == null || needle == null) {
return -1;
}
// 特殊情况
if (haystack.equals(needle)) {
return 0;
}
// needle的长度
int needleLength = needle.length();
// 遍历haystack并滑动窗口
for (int i = 0; i < haystack.length() - needleLength + 1; i++) {
// 检查子字符串是否等于needle
if (haystack.substring(i, i + needleLength).equals(needle)) {
return i;
}
}
return -1;
}
}
3.总结
浙公网安备 33010602011771号