程序员面试金典 17.11

Word Distance:在一个文本文件中,查找两个给定单词的最短距离。

只需要对文件扫描一次即可。假如已经知道了两个单词的第一次出现的位置,假设为Word1LastLocationWord2LastLocation,并有Word1LastLocation < Word2LastLocation,当从Word2LastLocation继续向右扫描时:

  • 如果再次遇到了word1,可以根据新老距离计算最小距离,同时更新Word1LastLocation,因为后面再次遇到word2时,这个距离肯定会更短一些
  • 如果再次遇到了word2,也可以根据新老距离计算最小距离,同时更新Word2LastLocation,因为后面再次遇到word1时,这个距离肯定会更短一些

为了避免麻烦的初始条件,提前做了两次find()找到了第一次出现的位置。

class Solution {
public:
    int findClosest(vector<string>& words, string word1, string word2) {
        int Word1LastLocation = find(words.begin(), words.end(), word1) - words.begin();
        int Word2LastLocation = find(words.begin(), words.end(), word2) - words.begin();
        int MinDistance = INT_MAX;
        int begin = Word1LastLocation < Word2LastLocation ? Word1LastLocation : Word2LastLocation;
        for(int i = begin; i < static_cast<int>(words.size()); i++)
        {
            if(words[i] == word1){
                Word1LastLocation = i;
            }
            else if(words[i] == word2){
                Word2LastLocation = i;
            }
            else;
            size_t tmp = abs(Word1LastLocation - Word2LastLocation);
            if(tmp < MinDistance){
                MinDistance = tmp;
            }
        }
        return MinDistance;
    }
};

更近一步,当对同文件进行多次不同单词距离的查找时,可以只通过一次遍历,将所有单词出现的每个位置存下来,然后在两个链表中交替前进查找最小距离。

代码中用的是multimap,一个key可以对应多个valuevalue会自动根据整型值大小排序。

class Solution {
public:
    int findClosest(vector<string>& words, string word1, string word2) {
        multimap<string, size_t> WordPositon;
        for(size_t i = 0; i < words.size(); i++)
        {
            WordPositon.insert(make_pair(words[i], i));
        }
        auto Word1LowerBound = WordPositon.lower_bound(word1);
        auto Word1UpperBound = WordPositon.upper_bound(word1);
        auto Word2LowerBound = WordPositon.lower_bound(word2);
        auto Word2UpperBound = WordPositon.upper_bound(word2);
        int MinDistance = words.size();
        for(multimap<string, size_t>::iterator iterWord1 = Word1LowerBound, iterWord2 = Word2LowerBound; iterWord1 != Word1UpperBound && iterWord2 != Word2UpperBound;)
        {
            int tmp = abs(int(iterWord1->second - iterWord2->second));
            if(tmp < MinDistance){
                MinDistance = tmp;
            }
            if(iterWord1->second < iterWord2->second){
                iterWord1++;
            }
            else{
                iterWord2++;
            }
        }
        return MinDistance;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值