# 实现 strStr() 函数。

给你两个字符串 haystackneedle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回  -1 。

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

# 示例

示例 1:

输入:haystack = "hello", needle = "ll"
输出:2
1
2

示例 2:

输入:haystack = "aaaaa", needle = "bba"
输出:-1
1
2

示例 3:

输入:haystack = "", needle = ""
输出:0
1
2

# 题解:

朴素解法 直观的解法是:枚举原字符串中每个字符作为发起点,每次从原字符串发起点和匹配串首位开始尝试匹配:

  • 匹配成功:返回本次匹配的原串 发起点
  • 匹配失败:枚举原串下一个 发起点,重新尝试匹配。

这里解释下为什么for循环的位置要到n-m的位置停下来, 就拿这个 hello 和 ll 来举例子就好。

0 1 2 3 4
h e l l o
    l l
1
2
3

hello 这个字符串的长度是5,ll的长度是2 按照这个减法的规则,循环到索引为3的位置就可以了,为什么?因为从索引为3的位置开始到原字符串的结尾刚好还有一个目标字符串的长度。 理解这个意思了吧,如果剩余的数量小于目标字符串的长度,循环和比较将会是没有意义的,会比较浪费性能。

/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
var strStr = function (haystack, needle) {
  let n = haystack.length;
  let m = needle.length;
  // n-m 这里简单做一个梳理:如果n和m 都是空的字符串
  // 内部的循环条件 while 不满足循环 b === m 都是0 此时返回i=0
  // 如果n比较长11 m也比较长8, 那么如果开头就开始匹配,匹配完成之后
  // 还剩下3个字符,就根本不需要继续走了
  
  for (let i = 0; i <= n - m; i++) {
    let a = i;
    let b = 0;
    // 不断向后匹配
    while (b < m && haystack.charAt(a) === needle.charAt(b)) {
      a++
      b++
    }
    if (b === m) {
      return i
    }
  }
  return -1;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
最后更新时间: 7/31/2023, 9:11:53 AM