243. Shortest Word Distance

本文探讨了在给定单词列表中寻找两个特定单词最短距离的两种算法实现。方法一采用两次遍历策略,记录每个目标单词的所有出现位置,然后进行两两比较找到最小距离。方法二则使用一次遍历,仅维护当前单词的最新位置,实时更新最短距离,显著提升了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值