持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}
}
总结
- 朴素算法的时间复杂度是O(n * n), 空间复杂度是O(n)
- 优化算法的时间复杂度是O(n), 空间复杂度是O(1)
- 朴素算法和优化算法都要掌握,才能更好的提升自己的解题能力!
- 坚持算法每日一题,加油!