[LeetCode] Shortest Word Distance II 最短單詞距離之二
This is a follow up of Shortest Word Distance. 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
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
這道題是之前那道Shortest Word Distance的拓展,不同的是這次我們需要多次呼叫求最短單詞距離的函式,那麼用之前那道題的解法二和三就非常不高效,而當時我們摒棄的解法一的思路卻可以用到這裡,我們用雜湊表來建立每個單詞和其所有出現的位置的對映,然後在找最短單詞距離時,我們只需要取出該單詞在雜湊表中對映的位置陣列進行兩兩比較即可,參見程式碼如下:
解法一:
class WordDistance { public: WordDistance(vector<string>& words) { for (int i = 0; i < words.size(); ++i) { m[words[i]].push_back(i); } } int shortest(string word1, string word2) { int res = INT_MAX; for (int i = 0; i < m[word1].size(); ++i) { for (int j = 0; j < m[word2].size(); ++j) { res = min(res, abs(m[word1][i] - m[word2][j])); } } return res; } private: unordered_map<string, vector<int> > m; };
我們可以優化上述的程式碼,使查詢的複雜度由上面的O(MN)變為O(M+N),其中M和N為兩個單詞的長度,我們需要兩個指標i和j來指向位置陣列中的某個位置,開始初始化都為0,然後比較位置陣列中的數字,將較小的一個的指標向後移動一位,直至其中一個數組遍歷完成即可,參見程式碼如下:
解法二:
class WordDistance { public: WordDistance(vector<string>& words) { for (int i = 0; i < words.size(); ++i) { m[words[i]].push_back(i); } } int shortest(string word1, string word2) { int i = 0, j = 0, res = INT_MAX; while (i < m[word1].size() && j < m[word2].size()) { res = min(res, abs(m[word1][i] - m[word2][j])); m[word1][i] < m[word2][j] ? ++i : ++j; } return res; } private: unordered_map<string, vector<int> > m; };
類似題目:
參考資料: