持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
有个内含单词的超大文本文件,给定任意两个不同的单词,找出在这个文件中这两个单词的最短距离(相隔单词数)。如果寻找过程在这个文件中会重复多次,而每次寻找的单词不同,你能对此优化吗?
示例:
输入:words = ["I","am","a","student","from","a","university","in","a","city"], word1 = "a", word2 = "student"
输出:1
提示:
words.length <= 100000
一次遍历
最直观的做法是遍历数组 ,对于数组中的每个 ,遍历数组 找到每个 并计算距离。该做法在最坏情况下的时间复杂度是 ,需要优化。
为了降低时间复杂度,需要考虑其他的做法。从左到右遍历数组 ,当遍历到 时,如果已经遍历的单词中存在 ,为了计算最短距离,应该取最后一个已经遍历到的 所在的下标,计算和当前下标的距离。同理,当遍历到 时,应该取最后一个已经遍历到的 所在的下标,计算和当前下标的距离。
基于上述分析,可以遍历数组一次得到最短距离,将时间复杂度降低到 。
用 和 分别表示数组 已经遍历的单词中的最后一个 的下标和最后一个 的下标,初始时 。遍历数组 ,当遇到 或 时,执行如下操作:
- 如果遇到 ,则将 更新为当前下标;如果遇到 ,则将 更新为当前下标。
- 如果 和 都非负,则计算两个下标的距离 ,并用该距离更新最短距离。
遍历结束之后即可得到 和 的最短距离。
var findClosest = function(words, word1, word2) {
const length = words.length;
let ans = length;
let index1 = -1, index2 = -1;
for (let i = 0; i < length; i++) {
const word = words[i];
if (word === word1) {
index1 = i;
} else if (word === word2) {
index2 = i;
}
if (index1 >= 0 && index2 >= 0) {
ans = Math.min(ans, Math.abs(index1 - index2));
}
}
return ans;
};