243. Shortest Word Distance
方法1: two pass
思路:
(错误的做法) hash所有单词和其出现的位置map<string, set<int>>,将word1和word2 set中的头尾/尾头差取较小值。这个方法遍历一遍数组就够了。
但是证明不对:第一不需要记录除了word1和word2以外的单词位置,第二如果是以下情况,可能是尾尾差值最小。如果是穿插在一起,也不是头尾头尾,必须pairwise比较。所以相当于worst case遍历两遍。
[“a”,“c”,“b”,“b”,“a”]
“a”
“b”
这种记index的方法只能最后pairwise的找出最小值。
Complexity
Time complexity: O(n)
Space complexity: O(n)
class Solution {
public:
int shortestDistance(vector<string>& words, string word1, string word2) {
vector<int> p1, p2;
int n = words.size();
for (int i = 0; i < n; i++){
if (words[i] == word1){
p1.push_back(i);
}
else if (words[i] == word2){
p2.push_back(i);
}
}
int result = INT_MAX;
for (auto i: p1){
for (auto j: p2){
result = min(result, abs(i - j));
}
}
return result;
//return min(abs(p1.back() - p2.front()), abs(p1.front() - p2.back()));
}
};
方法2:one pass
只用维持一个idx,因为将来遇到的最近一定是最晚出现的上一个单词。每次遇到新单词更新距离即可
Complexity
Time complexity: O(n)
Space complexity: O(1)
class Solution {
public:
int shortestDistance(vector<string>& words, string word1, string word2) {
int p1 = -1, p2 = -1;
int n = words.size();
int result = INT_MAX;
for (int i = 0; i < n; i++){
if (words[i] == word1){
p1 = i;
if (p2 != -1 ){
result = min(result, abs(p2 - p1));
}
}
if (words[i] == word2){
p2 = i;
if (p1 != -1 ){
result = min(result, abs(p2 - p1));
}
}
}
return result;
}
};
换一种写法:
class Solution2 {
public:
int shortestDistance(vector<string>& words, string word1, string word2) {
int p1 = -1, p2 = -1, result = INT_MAX;
for (int i = 0; i < words.size(); ++i) {
if (words[i] == word1)
p1 = i;
else if (words[i] == word2)
p2 = i;
if (p1 != -1 && p2 != -1)
result = min(result, abs(p1 - p2));
}
return result;
}
};