LeetCode最短单词距离问题(243、244、245)
243. 最短单词距离
给定一个单词列表和两个单词 word1 和 word2,返回列表中这两个单词之间的最短距离。可以假设 word1 不等于 word2,并且 word1 和 word2 都在列表里。
-
暴力法
遍历数组找到 i1 和 i2 在数组中所有出现的位置,并检查 ∣ i 1 − i 2 ∣ |i_1-i_2| ∣i1−i2∣是否比当前记录的最小值要小。
-
只遍历一次
我们可以记录两个下标 i1 和 i2 来显著提高暴力的时间复杂度,我们保存 word1 和 word2 的 最近 出现位置。每次我们发现一个新的单词出现位置,我们不需要遍历整个数组去找到另一个单词,因为我们已经记录了最近出现位置的下标。
int shortestDistance(vector<string>& words, string word1, string word2) {
int l=-1,r=-1;
int minDistance=words.size();
int currentDistance;
for(int i=0;i<words.size();i++)
{
if(words[i]==word1)
l=i;
else if(words[i]==word2)
r=i;
if(l!=-1 &&r!=-1)
minDistance=min(minDistance,abs(r-l));
}
return minDistance;
}
244. 最短单词距离 II
通过设计一个类,使类的构造函数能够接受一个单词列表,再实现一个方法找出两个单词的最小距离。同样,可以假设 word1 不等于 word2,并且 word1 和 word2 都在列表里。
-
哈希表
将每个单词以及下标存在哈希表中,然后对两个单词的哈希表进行访问,找出绝对值最小的下标差。
class WordDistance {
public:
unordered_map<string,vector<int>>mp;
WordDistance(vector<string>& words) {
int count=0;
for(auto x:words)
{
mp[x].push_back(count++);
}
}
int shortest(string word1, string word2) {
vector<int>l1=mp[word1],l2=mp[word2];
int res=INT_MAX;
for(auto x:l1)
{
for(auto y:l2)
{
res=abs(x-y)<res?abs(x-y):res;
}
}
return res;
}
};
245. 最短单词距离 III
给定一个单词列表和两个单词 word1 和 word2,返回列表中这两个单词之间的最短距离。
word1 和 word2 是有可能相同的,并且它们将分别表示为列表中两个独立的单词。
可以假设两个单词都在单词列表中。
-
哈希表
int shortestWordDistance(vector<string>& words, string word1, string word2) { unordered_map<string,vector<int>>mp; int count=0; for(auto x:words) //使用哈希表保存每个单词以及下标 { mp[x].push_back(count++); } if(word1!=word2) //如果两个单词不一样,则和 244 题情况一样 { vector<int>l1=mp[word1],l2=mp[word2]; int res=INT_MAX; for(auto x:l1) { for(auto y:l2) { res=abs(x-y)<res?abs(x-y):res; } } return res; }else //两个单词一样的话,考虑哈希表中对应的值中元素之间差的最小绝对值 { vector<int>l = mp[word1]; if(l.size()<=1) return 0; else{ vector<int> midd; for(int i=1;i<l.size();i++) midd.emplace_back(l[i]-l[i-1]); return *min_element(midd.begin(),midd.end()); } } }