[LeetCode] Word Ladder

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.

Note:

    • Return 0 if there is no such transformation sequence.
    • All words have the same length.
    • All words contain only lowercase alphabetic characters.

因为之前一直没自己写过Dijkstra算法,而且最开始感觉这题就是先转成图再用Dijkstra求最短路径,所以就一直没做,昨天复习了一下Dijkstra算法,打算把这题A掉,没想到居然爆内存了。

网上搜了下别人的代码,发现不用先转化成图,求边的时候直接枚举‘a’到‘z’就可以了,然后BFS。

 1 class Solution {
 2 public:
 3     int ladderLength(string start, string end, unordered_set<string> &dict) {
 4         if (start.length() != end.length()) return 0;
 5         if (start.empty() || end.empty()) return 0;
 6         queue<string> path;
 7         path.push(start);
 8         dict.erase(start);
 9         int len = 1, cnt = 1;
10         while (!dict.empty() && !path.empty()) {
11             string cur = path.front();
12             path.pop();
13             --cnt;
14             for (int i = 0; i < cur.size(); ++i) {
15                 string tmp = cur;
16                 for (char j = 'a'; j <= 'z'; ++j) {
17                     if (tmp[i] == j) continue;
18                     tmp[i] = j;
19                     if (tmp == end) return len + 1;
20                     if (dict.find(tmp) != dict.end()) {
21                         path.push(tmp);
22                         dict.erase(tmp);
23                     }
24                 }
25             }
26             if (cnt == 0) {
27                 ++len;
28                 cnt = path.size();
29             }
30         }
31         return 0;
32     }
33 };

下面是Dijsktra算法,不过超内存了。

 1 class Solution {
 2 public:
 3     bool match(const string &s1, const string &s2) {
 4         if (s1.length() != s2.length()) return false;
 5         int cnt = 0;
 6         for (int i = 0; i < s1.length(); ++i) {
 7             if (s1[i] != s2[i]) ++cnt;
 8             if (cnt > 1) return false;
 9         }
10         return cnt == 1 ? true : false;
11     }
12     
13     void buildGraph(vector<vector<int> > &graph, unordered_set<string> &dict, string start, string end, int &start_idx, int &end_idx) {
14         dict.insert(start);
15         dict.insert(end);
16         vector<string> str_idx(dict.size());
17         int idx = 0;
18         for (auto i : dict) {
19             str_idx[idx] = i;
20             if (i == start) start_idx = idx;
21             if (i == end) end_idx = idx;
22             ++idx;
23         }
24         graph.assign(str_idx.size(), vector<int>(str_idx.size(), INT_MAX));
25         for (int i = 0; i < str_idx.size(); ++i) {
26             for (int j = 0; j < str_idx.size(); ++j) {
27                 if (match(str_idx[i], str_idx[j])) {
28                     graph[i][j] = graph[j][i] = 1;
29                 }
30             }
31         }
32     }
33     
34     int dijkstra(vector<vector<int> > &graph, int start_idx, int end_idx) {
35         int N = graph.size();
36         vector<bool> s(N, false);
37         vector<int> dist(N, 0);
38         int u = start_idx;
39         for (int i = 0; i < N; ++i) {
40             dist[i] = graph[start_idx][i];
41         }
42         dist[start_idx] = 0;
43         s[start_idx] = true;
44         for (int i = 0; i < N; ++i) {
45             int tmp_max = INT_MAX;
46             for (int j = 0; j < N; ++j) {
47                 if (!s[j] && tmp_max > dist[j]) {
48                     u = j;
49                     tmp_max = dist[j];
50                 }
51             }
52             s[u] = true;
53             if (u == end_idx) return dist[u] + 1;
54             for (int j = 0; j < N; ++j) {
55                 if (!s[j] && graph[u][j] < INT_MAX) {
56                     dist[j] = min(dist[j], dist[u] + graph[u][j]);
57                 }
58             }
59         }
60     }
61     
62     int ladderLength(string start, string end, unordered_set<string> &dict) {
63         vector<vector<int> > graph;
64         int start_idx, end_idx;
65         buildGraph(graph, dict, start, end, start_idx, end_idx);
66         return dijkstra(graph, start_idx, end_idx);
67     }
68 };
原文地址:https://www.cnblogs.com/easonliu/p/4402054.html