28. 实现 strStr()『简单』
题目来源于力扣(LeetCode)
目录
一、题目
题目相关标签:双指针、字符串
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
二、解题思路
2.1 调用 indexOf() 方法
- 直接调用 Java 类库中 String 的 indexOf() 方法,返回目标字符串在源字符串中第一次出现的位置 (从0开始)。
2.2 代码实现 indexOf() 方法
-
分别将源字符串(haystack)与目标字符串(needle)转换成字符数组进行操作
-
定义字符变量 first 记录下目标字符串的首字符
-
遍历源字符数组,遍历长度限制在源字符数组的长度减目标字符数组的长度
-
在遍历过程中,直到匹配 first 变量记录的字符
-
找到匹配首字符后,如果索引未超过限定的长度,则开始比较后续的字符
-
循环内再定义一个 for 循环,匹配源字符数组与目标字符数组后续的字符
三、代码实现
3.1 调用 indexOf() 方法
public static int strStr(String haystack, String needle) {
return haystack.indexOf(needle);
}
3.2 代码实现 indexOf() 方法
public static int strStr(String haystack, String needle) {
// 排除特殊情况
if (null == needle || needle.length() == 0) {
return 0;
}
// 分别转换成字符数组进行操作
char[] sourceChars = haystack.toCharArray();
char[] targetChars = needle.toCharArray();
// target 数组中的第一个字符,首先要第一个字符正确匹配,才能匹配后续的字符
char targetFirst = targetChars[0];
// 源字符串需要遍历到的截止索引为:source 数组长度 - target 数组长度
int limit = sourceChars.length - targetChars.length;
for (int i = 0; i <= limit; i++) {
if (sourceChars[i] != targetFirst) {
// 源字符串中的元素直到匹配到目标字符串中的第一个字符
while (++i <= limit && sourceChars[i] != targetFirst) {
}
}
// 判断索引 i 是否仍小于等于 limit 索引
if (i <= limit) {
// 源字符串的开始比较索引:第一个匹配字符后一位的索引
int j = i + 1;
// 源字符串的结束比较索引:第一个匹配字符索引后一位的索引 + 目标字符串的结束索引
int end = j + targetChars.length - 1;
// 比较后续的字符是否匹配(不是 j <= end)
for (int k = 1; j < end && sourceChars[j] == targetChars[k]; j++, k++) {
}
// 当 j 增加了 targetChars.length - 2 个长度后,与 end 相同
// 即说明除第一个字符匹配外,后续字符也都正确匹配
if (j == end) {
return i;
}
}
}
// 源字符串中未找到目标字符串时,return -1
return -1;
}
四、执行用时
4.1 调用 indexOf() 方法
4.2 代码实现 indexOf() 方法
五、部分测试用例
public static void main(String[] args) {
String haystack = "hello", needle = "ll"; // output:2
// String haystack = "aaaaa", needle = "bba"; // output:-1
int result = strStr(haystack, needle);
System.out.println(result);
}