LeetCode算法-实现strStr()
题目描述
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = "hello", needle = "ll"
输出:2
示例 2:
输入:haystack = "aaaaa", needle = "bba"
输出:-1
示例 3:
输入:haystack = "", needle = ""
输出:0
提示:
- 0 <= haystack.length, needle.length <= 5 * 104
- haystack 和 needle 仅由小写英文字符组成
题目思路
我们采取暴力破解法,让我们的needle字符串与haystack的所有长度为needle长度的子串进行挨个的匹配,如果匹配成功,返回当前的下标,如果匹配都不成功,返回-1。如果haystack字符串的剩余长度小于needle字符串,则不用进行匹配,直接返回-1。
Java实现方案
public int strStr(String haystack, String needle) {
if (needle.length() == 0) {
return 0;
}
int sourceLength = haystack.length();
int targetLength = needle.length();
int result = -1;
for (int i = 0; i + targetLength <= sourceLength; i++) {
boolean flag = true;
for (int j = 0; j < targetLength; j++) {
if (needle.charAt(j) != haystack.charAt(i + j)) {
flag = false;
break;
}
}
if (flag) {
result = i;
break;
}
}
return result;
}
代码详细解析
由题目详情可知,如果needle字符串为空,我们要返回0。所以我们先对这种特殊情况进行一次处理,于是有了一下三行的代码。
if (needle.length() == 0) {
return 0;
}
小伙伴们,也许会问,如果我不处理,由下面的代码进行统一处理呢,那么一定是返回-1的,不符合题意,所以我们选择先行处理一次。
接下来,我们要获取两个字符串的长度,已经定义一个返回值,返回值我们默认为-1。因为除了上述情况外,其他所有不符合的情况都应该返回-1。于是有了下面的三行代码。
int sourceLength = haystack.length();
int targetLength = needle.length();
int result = -1;
接下来是我们的重头戏,遍历子串。我们先来看一眼for循环的条件。
for (int i = 0; i + targetLength <= sourceLength; i++) {}
我们定义一个下标初始的值为0,代表我们从haystack字符串的第一个字符开始进行对比。循环的条件是i + targetLength <= sourceLength。为什么是<=呢,因为我们要考虑的就是两个字符串长度相等的情况。比如a和a做比较,两个字符串的长度都为1。如果我们选择了<。那么0+1 < 1 这是不成立的。直接就会跳出循环,返回-1。而我们的正确结果是匹配成功应该返回0。所以我们在此进行匹配的时候,要选择<=。
有些小伙伴会考虑另一个问题,单看这个循环,如果i真的达到了等于的条件,那么不会产生数组越界吗?答案是不会的。因为我们下面的break判断会直接跳出当前的循环。
最后看下我们循环体里面的主代码逻辑
boolean flag = true;
for (int j = 0; j < targetLength; j++) {
if (needle.charAt(j) != haystack.charAt(i + j)) {
flag = false;
break;
}
}
if (flag) {
result = i;
break;
}
我们先设置一个flag 为true,他的意义代表,我们完全找到了这个子串,每次进入循环,我们都要重新置这个状态,因为我们是暴力破解,每次子串对比的状态一定要重置。
接下来开始遍历needle字符串。从第一个字符开始,因为随着我们的needle字符串,向后变更,haystack字符串也要同样的向后变更,所以haystack字符串为i+j作为下标。一旦有一个不一致,我们置flag为false然后跳出循环,当我们的needle字符串全部遍历完毕,而且没有跳出循环,此时的flag为true的话,那么i就是我们要找到的下表,直接跳出父循环,返回result即可。
总结
以上就是这道题的全部思路,欢迎大家在评论区进行探讨。