【LeetCode】单词距离Java题解

150 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

题目描述

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-closest-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析

  • 今天的算法题目是单词距离问题,题目以数组的形式展现,需要求解的是两个单词之间的最短距离。我们观察单词之间示例,最短距离即位当前的两个单词之间的索引的差值。
  • 很容易想到的解法是朴素解法,我们依次遍历 words 中的每一个单词,使用 hashMap 记录每一个 word1, word2 每一个单词的索引位置。把每个位置记录之后,我们可以采用循环遍历的方式,求出最小的单词距离。
  • 朴素算法通过之后,发现算法时间复杂度较高,很多的重复计算。我们可以优化一下思路,从 0 位置开始遍历数组,分别使用 idx1, idx2 记录word1, word2 的位置,当找到两个位置的时候,开始比较记录最短的距离。实现代码如下,供参考。

通过代码

  • 朴素解法
class Solution {
    public int findClosest(String[] words, String word1, String word2) {
        Map<String, List<Integer>> map = new HashMap<>();
        int n = words.length;
        for (int i = 0; i < n; i++) {
            List<Integer> idxs = map.getOrDefault(words[i], new ArrayList<>());
            idxs.add(i);
            map.put(words[i], idxs);
        }

        int ans = Integer.MAX_VALUE;

        List<Integer> word1Idxs = map.getOrDefault(word1, new ArrayList<>());
        List<Integer> word2Idxs = map.getOrDefault(word2, new ArrayList<>());

        for (int j = 0; j < word1Idxs.size(); j++) {
            for (int k = 0; k < word2Idxs.size(); k++) {
                ans = Math.min(ans, Math.abs(word1Idxs.get(j) - word2Idxs.get(k)));
            }
        }
        
        return ans;
    }
}
  • 优化解法
class Solution {
    public int findClosest(String[] words, String word1, String word2) {
        int n = words.length;
        int ans = Integer.MAX_VALUE;
        int idx1 = -1;
        int idx2 = -1;
        for (int i = 0; i < n; i++) {
            if (words[i].equals(word1)) {
                idx1 = i;
            } else if (words[i].equals(word2)) {
                idx2 = i;
            }
            if (idx1 >= 0 && idx2 >= 0) {
                ans = Math.min(ans, Math.abs(idx1 - idx2));
            }
        }

        return ans;
    }
}  

image.png

总结

  • 朴素算法的时间复杂度是O(n * n), 空间复杂度是O(n)
  • 优化算法的时间复杂度是O(n), 空间复杂度是O(1)
  • 朴素算法和优化算法都要掌握,才能更好的提升自己的解题能力!
  • 坚持算法每日一题,加油!