Two methods. Hashmap is not quite useful here.
#include <string>
#include <vector>
#include <iostream>
#include <climits>
#include <unordered_map>
using namespace std;
/*
Given a list of words and two words word1 and word2, return the shorest distance between these
two words in the list.
for example:
words = ["practise", "make", "perfect", "coding", "makes"]
word1 = "coding", word2 = "practice", return 3.
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.
*/
// method1, remember two words' index and caculate the distance. O(N) time. O(1) space.
int shortestDistance(vector<string>& words, string word1, string word2) {
int index_1 = -1;
int index_2 = -1;
int minDistance = INT_MAX;
for(int i = 0; i < words.size(); ++i) {
if(words[i] == word1) index_1 = i;
if(words[i] == word2) index_2 = i;
if(index_1 != -1 && index_2 != -1) {
minDistance = min(minDistance, abs(index_1 - index_2));
}
}
return minDistance;
}
// method2: we can use hashmap. O(N) time, O(N) space.
int shortestDistanceII(vector<string>& words, string word1, string word2) {
unordered_map<string, int> wordsToIndex;
int minDistance = INT_MAX;
for(int i = 0; i < words.size(); ++i) {
auto iter_word1 = wordsToIndex.find(word1);
auto iter_word2 = wordsToIndex.find(word2);
// unordered_map only support unique key insert. duplicates using unordered_multimap.
if(iter_word1 == wordsToIndex.end()) wordsToIndex.insert({words[i], i});
else wordsToIndex[words[i]] = i;
if(iter_word2 == wordsToIndex.end()) wordsToIndex.insert({words[i], i});
else wordsToIndex[words[i]] = i;
if((iter_word1 != wordsToIndex.end()) && (iter_word2 != wordsToIndex.end())) {
minDistance = min(minDistance, abs(iter_word1->second - iter_word2->second));
}
}
return minDistance;
}
int main(void) {
vector<string> words{"practise", "make", "perfect", "coding", "make"};
int dis = shortestDistanceII(words, "make", "coding");
cout << dis << endl;
}