单词距离

原题在这里

  概述题意,给定一个字符串数组和两个指定字符串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 @ 2022-05-27 09:59  Renhr  阅读(24)  评论(0)    收藏  举报