单词距离

原题在这里

  概述题意,给定一个字符串数组和两个指定字符串x,y,问xy在数组内的最小下标间距。

analyse:

  很不好意思的是,这个题目我想复杂了,如下:

    运用链式前向星,将每一个字符串的哈希值与其下标相连成边,建边完成后,双指针遍历两个字符串的下标数组得到ans。

  实际上,在数组遍历建边过程中,每一次得到指定字符串,处理一次下标间距即可

    因为每次出现一次指定字符串,即与上一次另一个字符串出现的下标数组而言,一定是最后一次生效,这个过程不断循环,才会得到两个字符串的数组下标。

  最后,即便是我最初的那个写法,也不应该那么写,直接建立两个数组,每次遇到指定字符串直接添加,最后再比较即可。

code:

复制代码
class Solution
{
public:
    int findClosest(vector<string> &words, string word1, string word2)
    {
        //直接追下标更新值即可
        int n = words.size(), ans = n, l = 0, r = 0;
        for (int i = 0; i < n; ++i)
        {
            if (words[i] == word1)
                l = i + 1;
            if (words[i] == word2)
                r = i + 1;
            if (l > 0 && r > 0)
                ans = min(ans, abs(l - r));
        }
        return ans;
    }
};
复制代码
复制代码
class Solution
{
    vector<int> head;
    int num = 0;
    struct ii
    {
        int to, next;
        ii(int x, int y) : to(x), next(y){};
    };
    vector<ii> edge;
    void add(int x, int y) //字符码->下标
    {
        edge.emplace_back(y, head[x]);
        head[x] = num++;
    }
    int find(int x, int y)
    {
        int l = head[x], r = head[y], ans = 1e6 + 9;
        while (l && r) //存在下标从1开始
        {
            //往差值更小递进
            cout << edge[l].to << "<->" << edge[r].to << endl;
            ans = min(ans, abs(edge[l].to - edge[r].to));
            int nl = edge[l].next, nr = edge[r].next;
            //优先取非0
            if (nl == nr && nl == 0)
                break;
            else if (nl == 0)
                r = edge[r].next;
            else if (nr == 0)
                l = edge[l].next;
            else if (edge[l].to > edge[r].to) // nl更近
                l = edge[l].next;
            else
                r = edge[r].next;
        }
        return ans;
    }

public:
    int findClosest(vector<string> &words, string word1, string word2)
    {
        //最佳方案是将字符串哈希处理
        /*
        analyse:
            如图链式前向星处理得到两个单词的下标vector
        */
        head = vector<int>(1e6 + 9);
        int id = 0;
        map<string, int> mp;
        mp.clear();
        for (int i = 0; i < words.size(); ++i)
        {
            if (mp.count(words[i]))
                add(mp[words[i]], i + 1);
            else
                add(mp[words[i]] = ++id, i + 1);
        }
        return find(mp[word1], mp[word2]);
    }
};
原思路解法
复制代码
复制代码
class Solution
{
public:
    int findClosest(vector<string> &words, string word1, string word2)
    {
        vector<int> x, y;
        int n = words.size(), ans = n;
        for (int i = 0; i < n; ++i)
        {
            if (words[i] == word1)
                x.emplace_back(i);
            if (words[i] == word2)
                y.emplace_back(i);
        }
        int l = x.size() - 1, r = y.size() - 1;
        while (l >= 0 && r >= 0)
        {
            ans = min(ans, abs(x[l] - y[r]));
            if (l == 0 && r == 0)
                break;
            if (l == 0)
                --r;
            else if (r == 0)
                --l;
            else if (x[l] > y[r])
                --l;
            else
                --r;
        }
        return ans;
    }
};
原思路优化做法(与标准做法时间复杂度相近)
复制代码

【Over】

posted @   Renhr  阅读(18)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示