题目
有个内含单词的超大文本文件,给定任意两个不同的单词,找出在这个文件中这两个单词的最短距离(相隔单词数)。如果寻找过程在这个文件中会重复多次,而每次寻找的单词不同,你能对此优化吗?
示例
输入:words = ["I","am","a","student","from","a","university","in","a","city"], word1 = "a", word2 = "student"
输出:1
复制代码
题解
枚举+二分
这不是很简单,将第一个单词的位置记录到 indexs 数组中,并且知道数组单调递增,枚举第二个单词的位置 x,用二分法查找在 indexs 与 x 最近接近的值;求出所有值的最小值即为答案
代码如下:
var findClosest = function (words, word1, word2) {
if (word1 === word2) return 0;
const len = words.length;
let indexs = [];
for (let i = 0; i < len; i++) {
if (words[i] === word1) indexs.push(i);
}
//console.log(indexs)
let min = 100000;
for (let i = 0; i < len; i++) {
if (words[i] === word2) {
min = Math.min(min, query(i));
}
}
function query(x) {
if (x < indexs[0]) {
return indexs[0] - x;
}
if (x > indexs[indexs.length - 1]) {
return x - indexs[indexs.length - 1];
}
let left = 0;
let right = indexs.length - 1;
let l = 0;
let r = right;
while (left < right) {
const m = Math.floor((left + right) / 2);
if (indexs[m] === x) return 0;
if (indexs[m] < x) {
l = m;
left = m + 1;
} else {
r = m;
right = m - 1;
}
}
return Math.min(
Math.abs(x - indexs[l]),
Math.abs(x - indexs[left]),
Math.abs(x - indexs[r])
);
}
return min;
};
复制代码
枚举
不需要记录第一个单词所有的位置,也不需要将第一个单词位置全部记录再去找第二个位置;在枚举过程中,记录两个单词最后一次出现的位置,两位置绝对值之差最小值即为所求
代码如下
var findClosest = function (words, word1, word2) {
const len = words.length;
let left = null;
let right = null;
let min = len;
for (let i = 0; i < len; i++) {
if (words[i] === word1) {
left = i;
}
if (words[i] === word2) {
right = i;
}
if (left !== null && right !== null) {
min = Math.min(min, Math.abs(right - left));
}
}
return min;
};
复制代码