LeetCode 算法:单词距离

115 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 26 天,点击查看活动详情

单词距离

原题地址

有个内含单词的超大文本文件,给定任意两个不同的单词,找出在这个文件中这两个单词的最短距离(相隔单词数)。如果寻找过程在这个文件中会重复多次,而每次寻找的单词不同,你能对此优化吗?

示例:

输入:words = ["I","am","a","student","from","a","university","in","a","city"], word1 = "a", word2 = "student"
输出:1

提示:

  • words.length <= 100000

思路分析

方法一

  1. 题目中要求找到两个单词的最短距离,原本以为可以使用数组的 findIndex 方法找到第一个出现的下标,然后相减得到绝对值就是所需要的结果,但是在测试用例运行时出错了;
  2. 后来分析题目后,得到并不是第一个出现的下标之间的距离是最短的,那么我们可以把出现的所有下标都找出来;
  3. num1 来记录 word1 出现的下标数组,num2 来记录 word2 出现的下标数组;
  4. 在获取到每个单词出现的下标数组后,首先给结果定义一个较大的值,对于该题目来说,最大值一定不会超过 words.length,定义完成后,双层遍历 num1num2,然后取对应的初值与 Math.abs(num1[i] - num2[j]) 之间的最小值,遍历结束后,也就得到了最终的 res 值。

方法二

  1. 方法一种是先进行一次遍历将对应的下标数组找出来,然后再进行双层遍历得到最后的结果;
  2. 那么,我们来考虑是否可以在一次遍历之中将结果拿到呢。给结果定义一个较大的值,然后定义 index1index2 分别存储 word1word2words 中出现的下标,初始定义为 -1。在遍历过程中找到对应的下标,将 index1index2 进行赋值,然后在它俩都不为 -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

END