Word Ladder

2014.2.27 02:14

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.

Solution:

  At first I tried to use Dijkstra's Algorithm on this problem, as I saw a graph in the words. But it proved to be unnecessary and inefficient.

  Use BFS and queue instead and you'll make it.

  One thing is very important: don't check if two words differ only by one letter, you should change one letter and see if it is still in the dictionary. This saves a lot of time.

  Total time complexity is O(n^2). Space complexity is O(n). The constant factor is relatively large, so the algorithm is still expensive.

Accepted code:

 1 // 7CE, 4RE, 4TLE, 1AC, BFS...
 2 #include <queue>
 3 #include <string>
 4 #include <unordered_map>
 5 #include <unordered_set>
 6 using namespace std;
 7 
 8 class Solution {
 9 public:
10     int ladderLength(string start, string end, unordered_set<string> &dict) {
11         queue<pair<string, int> > qq;
12         string word, next_word;
13         unordered_map<string, int> um;
14         char ch, old_ch;
15         int result = 0;
16         bool suc = false;
17         pair<string, int> this_pair;
18         
19         qq.push(make_pair(start, 1));
20         um[start] = 1;
21         while (!qq.empty()) {
22             this_pair = qq.front();
23             qq.pop();
24             word = this_pair.first;
25             for (size_t i = 0; i < word.length(); ++i) {
26                 old_ch = word[i];
27                 for (ch = 'a'; ch <= 'z'; ++ch) {
28                     word[i] = ch;
29                     if (word == end) {
30                         suc = true;
31                         result = this_pair.second + 1;
32                     }
33                     if (um.find(word) == um.end() && dict.find(word) != dict.end()) {
34                         qq.push(make_pair(word, this_pair.second + 1));
35                         um[word] = this_pair.second + 1;
36                     }
37                 }
38                 if (suc) {
39                     break;
40                 }
41                 word[i] = old_ch;
42             }
43             if (suc) {
44                 break;
45             }
46         }
47         while(!qq.empty()) {
48             qq.pop();
49         }
50         return result;
51     }
52 };

 

 posted on 2014-02-27 02:45  zhuli19901106  阅读(464)  评论(0编辑  收藏  举报