244 Shortest Word Distance II

This is a follow up of Shortest Word Distancearrow-up-right. The only difference is now you are given the list of words and your method will be called repeatedly many times with different parameters. How would you optimize it?

Design a class which receives a list of words in the constructor, and implements a method that takes two words word1 and word2 and return the shortest distance between these two words in the list.

For example, Assume that words =["practice", "makes", "perfect", "coding", "makes"].

Given word1= “coding”, word2 =“practice”, return 3. Given word1= "makes", word2 ="coding", return 1.

Note: You may assume that word1 does not equal to word2, and word1 and word2 are both in the list.

The Idea: First I considered doing O(n^2) preprocessing and create a lookup table to find the shortest distances between words, but this got TLE. The alternative approach would be to just map the occurrences into a dictionary and return the return the minimum absolute difference between the two lists in linear time. This gets AC, but repeatedly calling this more than N times would in worst case have a higher complexity than O(n^2) time.

Complexity: O(n) time for init and shortest. O(n) space.

from collections import defaultdict
import sys


class WordDistance:

    def __init__(self, words):
        """
        :type words: List[str]
        """
        self.d = defaultdict(list)
        for i, word in enumerate(words):
            self.d[word].append(i)


    def shortest(self, word1, word2):
        """
        :type word1: str
        :type word2: str
        :rtype: int
        """

        if word1 == word2:
            return 0

        dist = sys.maxsize
        for loc1 in self.d[word1]:
            for loc2 in self.d[word2]:
                dist = min(dist, abs(loc1 - loc2))
        return dist

# Your WordDistance object will be instantiated and called as such:
# obj = WordDistance(words)
# param_1 = obj.shortest(word1,word2)

Last updated