携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 28 天,点击查看活动详情
多次搜索
原题地址
给定一个较长字符串 big 和一个包含较短字符串的数组 smalls,设计一个方法,根据 smalls 中的每一个较短字符串,对 big 进行搜索。输出 smalls 中的字符串在 big 里出现的所有位置 positions,其中positions[i]为smalls[i]出现的所有位置。
示例:
输入:
big = "mississippi"
smalls = ["is","ppi","hi","sis","i","ssippi"]
输出: [[1,4],[8],[],[3],[1,4,7,10],[5]]
提示:
0 <= len(big) <= 10000 <= len(smalls[i]) <= 1000smalls的总字符数不会超过100000。- 你可以认为
smalls中没有重复字符串。 - 所有出现的字符均为英文小写字母。
思路分析
方法一
- 先使用暴力搜索,遍历
smalls,分别找出smalls中每个字符串在big中的位置记录下来; - 拿到
smalls中的每个字符串后,遍历big字符串,然后取以i为开头smalls[i]的字符串长度的字符,判断是否跟smalls[i]相同,若相同则将i记录下来存储到temp中,然后在遍历big结束后将temp存入res中; - 在提交运行测试用例后,发现有一个用例报错,是在
smalls中的元素为空字符串时报错的,于是在判断条件中增加元素不为空的判断即可。
方法二
- 方法二中使用 indexOf 的方法来寻找下标;
- 定义一个 findAllIndex 的方法来寻找 big 中字符串 str 出现的下标,indexOf 接受两个参数,一个是要寻找的字符串,第二个是要从哪个位置开始寻找;
- 遍历 smalls 数组,然后使用 findAllIndex 找到所有下标后,存储在 res 中,返回即可。
AC 代码
方法一
/**
* @param {string} big
* @param {string[]} smalls
* @return {number[][]}
*/
var multiSearch = function(big, smalls) {
const res = []
smalls.forEach(item => {
const len = item.length
const temp = []
for(let i = 0; i < big.length; i++) {
if(big.substr(i, len) === item && item) {
temp.push(i)
}
}
res.push(temp)
})
return res
};
结果:
- 执行结果: 通过
- 执行用时:268 ms, 在所有 JavaScript 提交中击败了53.85%的用户
- 内存消耗:62.4 MB, 在所有 JavaScript 提交中击败了38.46%的用户
- 通过测试用例:32 / 32
方法二
/**
* @param {string} big
* @param {string[]} smalls
* @return {number[][]}
*/
var multiSearch = function(big, smalls) {
const res = []
const findAllIndex = (str) => {
if(!str) return []
let i = 0, result = []
while(i < big.length){
let index = big.indexOf(str, i)
if(index === -1) break
else {
result.push(index)
i = index + 1
}
}
return result
}
smalls.forEach(item => {
res.push(findAllIndex(item))
})
return res
};
结果:
- 执行结果: 通过
- 执行用时:260 ms, 在所有 JavaScript 提交中击败了63.08%的用户
- 内存消耗:61 MB, 在所有 JavaScript 提交中击败了75.38%的用户
- 通过测试用例:32 / 32