这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战
题目描述
实现一个 strStr 函数。参数传入2个字符串,haystack和needle。需要找到needle字符串在haystack字符串第一次出现的位置(索引)。如果找不到,则返回-1。
如果needle字符串是空字符串,则返回0。
举个例子:
参数a: 'abcaaa'
参数b: 'aaa'
返回: 3
参数a: 'abcaaa'
参数b: 'bc'
返回: 1
参数a: 'abcaaa'
参数b: 'ddd'
返回: -1
参数a: 'abcaaa'
参数b: ''
返回: 0
思路分析
第一种方法
首先判断如果needle是空字符串则返回0。
下面
nLen指的是needle的长度。
使用双层遍历嵌套,第一层只需遍历索引小于等于haystack.length - nLen的元素,因为大于的元素不会再等于needle。
第二层再遍历从第一层当前索引开始的nLen长度,判断haystack的这部分元素是否和needle是否一一相等,如果相等,则返回第一层的索引。
最后结束遍历如果都不相等,则返回-1。
代码如下:
/**
* @param {string} haystack
* @param {string} needle
* @return {number}
*/
var strStr = function (haystack, needle) {
const nLen = needle.length
if (!nLen) return 0
for (let i = 0; i <= haystack.length - nLen; i++) {
for (let j = 0; j < nLen; j++) {
if (haystack[i + j] !== needle[j]) {
break
}
if (j === nLen - 1) return i
}
}
return -1
};
第二种方法
因为第一种方法使用遍历嵌套,导致复杂度变大,所以耗时变长了。
下面来看看第二种方法。
我们也是对索引小于等于haystack.length - nLen的元素进行遍历,然后每次遍历都要判断当前遍历的元素是否和needle的第一个元素是否相等。
如果不相等,则继续进行下次遍历。
如果相等,则对haystack,从当前索引开始,截取nLen长度的字符串(使用的slice方法)判断是否和needle相等,相等则直接返回当前的索引。
如果遍历结束后,没有相等的,则返回-1。
/**
* @param {string} haystack
* @param {string} needle
* @return {number}
*/
var strStr = function (haystack, needle) {
const nLen = needle.length
if (!nLen) return 0
for (let i = 0; i <= haystack.length - nLen; i++) {
const s = haystack[i];
if (s === needle[0] && haystack.slice(i, i + nLen) === needle) {
return i
}
}
return -1
};