【leetcode】Word Ladder (hard) ★

Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the dictionary

For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

思路:

找两点之间的最小距离,感觉只能用图,构建图的邻接矩阵,然后folyd 果断的超时了.....

int ladderLength1(string start, string end, unordered_set<string> &dict) {
        if(start == end) return 1;
        int vexnum = dict.size() + 2;
        if(dict.find(start) != dict.end()) vexnum--;
        if(dict.find(end) != dict.end()) vexnum--;
        vector<string> s(vexnum); //记录graph中每行代表的单词
        vector<vector<int>> graph(vexnum, vector<int>(vexnum, vexnum + 1)); //邻接矩阵
        s[0] = start;
        s.back() = end;
        int i = 1;
        unordered_set<string>::iterator it;
        for(it = dict.begin(); it != dict.end(); it++)
        {
            if(*it != start && *it != end)
                s[i++] = (*it);
        }

        //记录有哪些单词可以通过一次变化相互转换
        for(i = 0; i < s.size(); i++)
        {
            string temp = s[i];
            for(int j = 0; j < start.size(); j++)
            {
                for(char c = 'a'; c <= 'z'; c++)
                {
                    temp[j] = c;
                    if(dict.find(temp) != dict.end())
                    {
                        int edge = find(s.begin(), s.end(), temp) - s.begin();
                        if(edge == i)
                        {
                            graph[i][edge] = 0;
                            graph[edge][i] = 0;
                        }
                        else
                        {
                            graph[i][edge] = 1;
                            graph[edge][i] = 1;
                        }
                    }
                }
            }
        }

        for(int k = 0; k < graph.size(); k++)
        {
            for(int i = 0; i < graph.size(); i++)
            {
                for(int j = 0; j < graph.size(); j++)
                {
                    if(graph[i][j] > graph[i][k] + graph[k][j])
                    {
                        graph[i][j] = graph[i][k] + graph[k][j];
                    }
                }
            }
        }

        return (graph[0][vexnum - 1] == vexnum + 1) ? 0 : graph[0][vexnum - 1] + 1;
    }

来看大神的BFS算法,用dis记录每个点到start的距离。队列里开始只有start, 然后每次遇到新转化成的单词就进队列,更新距离。判断能否转化时用字符长度和26个字母,而不是对字典遍历,因为字典中单词的数量可能远大于26个。

int ladderLength(string start, string end, unordered_set<string> &dict)
    {
        unordered_map<string, int> dis;
        queue<string> q;
        dis[start] = 1;
        q.push(start);
        while(!q.empty())
        {
            string word = q.front(); q.pop();
            for(int i = 0; i < start.size(); i++)
            {
                string temp = word;
                for(char c = 'a'; c <= 'z'; c++)
                {
                    temp[i] = c;
                    if(dict.count(temp) > 0 && dis.count(temp) == 0)
                    {
                        dis[temp] = dis[word] + 1;
                        q.push(temp);
                    }
                }
            }
        }
        if(dis.count(end) == 0) return 0;
        return dis[end];
    }
原文地址:https://www.cnblogs.com/dplearning/p/4268705.html