携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 26 天,点击查看活动详情
单词距离
原题地址
有个内含单词的超大文本文件,给定任意两个不同的单词,找出在这个文件中这两个单词的最短距离(相隔单词数)。如果寻找过程在这个文件中会重复多次,而每次寻找的单词不同,你能对此优化吗?
示例:
输入:words = ["I","am","a","student","from","a","university","in","a","city"], word1 = "a", word2 = "student"
输出:1
提示:
words.length <= 100000
思路分析
方法一
- 题目中要求找到两个单词的最短距离,原本以为可以使用数组的
findIndex方法找到第一个出现的下标,然后相减得到绝对值就是所需要的结果,但是在测试用例运行时出错了; - 后来分析题目后,得到并不是第一个出现的下标之间的距离是最短的,那么我们可以把出现的所有下标都找出来;
num1来记录word1出现的下标数组,num2来记录word2出现的下标数组;- 在获取到每个单词出现的下标数组后,首先给结果定义一个较大的值,对于该题目来说,最大值一定不会超过
words.length,定义完成后,双层遍历num1和num2,然后取对应的初值与Math.abs(num1[i] - num2[j])之间的最小值,遍历结束后,也就得到了最终的res值。
方法二
- 方法一种是先进行一次遍历将对应的下标数组找出来,然后再进行双层遍历得到最后的结果;
- 那么,我们来考虑是否可以在一次遍历之中将结果拿到呢。给结果定义一个较大的值,然后定义
index1和index2分别存储word1和word2在words中出现的下标,初始定义为-1。在遍历过程中找到对应的下标,将index1和index2进行赋值,然后在它俩都不为-1时,进行相减寻找距离,并与结果相比获取更小距离进行更新,最后在遍历结束后得到对应的结果。
AC 代码
方法一
/**
* @param {string[]} words
* @param {string} word1
* @param {string} word2
* @return {number}
*/
var findClosest = function(words, word1, word2) {
const num1 = []
const num2 = []
words.forEach((item, index) => {
if(item === word1) num1.push(index)
if(item === word2) num2.push(index)
})
let res = words.length
for(let i = 0; i < num1.length; i++) {
for(let j = 0; j < num2.length; j++) {
res = Math.min(Math.abs(num1[i] - num2[j]), res)
}
}
return res
};
结果:
- 执行结果: 通过
- 执行用时:96 ms, 在所有 JavaScript 提交中击败了48.82%的用户
- 内存消耗:49.1 MB, 在所有 JavaScript 提交中击败了18.98%的用户
- 通过测试用例:43 / 43
方法二
/**
* @param {string[]} words
* @param {string} word1
* @param {string} word2
* @return {number}
*/
var findClosest = function(words, word1, word2) {
const len = words.length
let res = len
let index1 = -1, index2 = -1
for (let i = 0; i < len; i++) {
const word = words[i]
if (word === word1) {
index1 = i
}
if (word === word2) {
index2 = i
}
if (index1 >= 0 && index2 >= 0) {
res = Math.min(res, Math.abs(index1 - index2))
}
}
return res
};
结果:
- 执行结果: 通过
- 执行用时:80 ms, 在所有 JavaScript 提交中击败了96.27%的用户
- 内存消耗:48.4 MB, 在所有 JavaScript 提交中击败了53.89%的用户
- 通过测试用例:43 / 43