美文网首页
面试题 17.11. 单词距离

面试题 17.11. 单词距离

作者: Abeants | 来源:发表于2022-05-28 18:08 被阅读0次

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

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

    提示:
    words.length <= 100000

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

    解题思路及方法

    读题感觉很简单,一次遍历即可,但如果是直接遍历数组words,对于数组中的每个word1,遍历数组words 找到每个word2,并计算距离,该做法在最坏情况下的时间复杂度是 O(n^2),需要优化。

    优化的方式是:由于单词在words数组中位置是按升序存在的,所以之前已经计算过距离的,就不用再计算,因为距离肯定大于现在计算的两个单词距离。即从左到右遍历数组words,当遍历到word1时,如果已经遍历的单词中存在word2,为了计算最短距离,应该取最后一个已经遍历到的word2所在的下标,计算和当前下标的距离。同理,当遍历到word2时,应该取最后一个已经遍历到的word1所在的下标,计算和当前下标的距离,该算法时间复杂度是 O(n)。但是进阶要求如果寻找过程在这个文件中会重复多次,而每次寻找的单词不同,你能对此优化吗?当看到文件很大,要求查找效率的时候,就用哈希表,因为查找效率高。

    用一个哈希表记录每个单词出现的下标,然后调用该函数时传入两个单词的参数,最后用双指针计算下标中的最小距离。

    class Solution {
        public int findClosest(String[] words, String word1, String word2) {
            int n = words.length;
            if (n < 2) return 0;
    
            Map<String, List<Integer>> pos = new HashMap<>();
            // 遍历words按升序记录每个单词的所有位置
            for (int i = 0; i < n; i++) {
                String str = words[i];
                List<Integer> list = pos.getOrDefault(str, new ArrayList<>());
                list.add(i);
                pos.put(str, list);
            }
    
            // 计算最短距离
            int min = Integer.MAX_VALUE;
            for (int pos1 : pos.get(word1)) {
                for (int pos2 : pos.get(word2)) {
                    min = Math.min(min, Math.abs(pos1 - pos2));
                }
            }
            
            return min;
        }
    }
    

    结果如下:

    相关文章

      网友评论

          本文标题:面试题 17.11. 单词距离

          本文链接:https://www.haomeiwen.com/subject/abziprtx.html