runnig

word ladder

Feb 15th, 2013
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.63 KB | None | 0 0
  1. #include <iostream>
  2. #include <utility>
  3. #include <unordered_set>
  4. #include <unordered_map>
  5. #include <string>
  6. #include <vector>
  7. #include <deque>
  8. #include <functional>
  9. #include <stdint.h>
  10.  
  11. using namespace std;
  12.  
  13. typedef unordered_set<string> dict_t;
  14. typedef unordered_map<int, vector<int> > graph_t;
  15.  
  16. typedef uint16_t vertex_t;
  17. typedef uint32_t edge_t;
  18. typedef std::unordered_set<edge_t> edge_set_t;
  19.  
  20.  
  21. edge_t make_edge(vertex_t i, vertex_t j)
  22. {
  23.     if(i > j) { swap(i,j); }
  24.     return ((0xFFFF&i)<<16) + (0xFFFF&j);
  25. }
  26.  
  27. void connect(graph_t & G, edge_set_t & edges, vertex_t i, vertex_t j)
  28. {
  29.     G[i].push_back(j);
  30.     G[j].push_back(i);
  31.     edges.insert(make_edge(i,j));
  32. }
  33.  
  34. class Solution {
  35. public:
  36.  
  37.     int distance(const vector<string> & svec, int a, int b,
  38.         size_t word_len)
  39.     {
  40.         const string & sa = svec[a];
  41.         const string & sb = svec[b];
  42.  
  43.         const size_t & N = word_len;
  44.  
  45.         if(a > b) { std::swap(a,b); }
  46.  
  47.         int num_diff = 0;
  48.         size_t i;
  49.  
  50.         for(i=0; i < N/2; ++i)
  51.         {
  52.             if(sa[i] != sb[i] && ++num_diff > 1)
  53.             {
  54.                 return num_diff;
  55.             }
  56.             if(sa[N-1-i] != sb[N-1-i] && ++num_diff > 1)
  57.             {
  58.                 return num_diff;
  59.             }
  60.         }
  61.         if(N%2 != 0 && sa[N/2] != sb[N/2] && ++num_diff > 1)
  62.         {
  63.             return num_diff;
  64.         }
  65.         return num_diff;
  66.     }
  67.  
  68.     typedef dict_t::iterator dict_pos_t;
  69.  
  70.     int ladderLength(string start, string end, dict_t &dict)
  71.     {  
  72.         const size_t word_len = start.size();
  73.  
  74.         start += 's';
  75.         end += 'e';
  76.  
  77.         dict.insert(start);
  78.         dict.insert(end);
  79.  
  80.         const size_t NUM_WORDS = dict.size();
  81.         vector<string> svec(NUM_WORDS);
  82.  
  83.         dict_t::iterator it = dict.begin();
  84.  
  85.         size_t start_pos, end_pos;
  86.  
  87.         std::hash<std::string> hash_fn;
  88.  
  89.         const size_t start_hash = hash_fn(start);
  90.         const size_t end_hash = hash_fn(end);
  91.  
  92.         for(size_t i = 0; it != dict.end(); ++it, ++i)
  93.         {
  94.             const string & S = *it;
  95.             const size_t h = hash_fn(S);
  96.             if(h == start_hash) { start_pos = i; }
  97.             if(h == end_hash) { end_pos = i; }
  98.             svec[i] = S;
  99.         }
  100.  
  101.         bool entrance_found = false, exit_found = false;
  102.         graph_t G;
  103.  
  104.         edge_set_t edges;
  105.        
  106.         for(size_t i = 0; i < NUM_WORDS; ++i)
  107.         {
  108.             if(i == start_pos || i == end_pos) { continue; }
  109.                
  110.             int d;
  111.                
  112.             d = distance(svec, start_pos, i, word_len);
  113.             if(d == 1)
  114.             {
  115.                 //connect(G, edges, start_pos, i);
  116.                 entrance_found = true;
  117.             }
  118.                
  119.             d = distance(svec, end_pos, i, word_len);
  120.             if(d == 1)
  121.             {
  122.                 //connect(G, edges, end_pos, i);
  123.                 exit_found = true;
  124.             }
  125.  
  126.         }
  127.  
  128.         if(!entrance_found || !exit_found) { return 0; }
  129.  
  130.         for(size_t i = 0; i < NUM_WORDS-1; ++i)
  131.         {
  132.             for(size_t j = i+1; j < NUM_WORDS; ++j)
  133.             {
  134.                 if(edges.find(make_edge(i,j)) != edges.end()) { continue; }
  135.  
  136.                 const string & si = svec[i];
  137.                 const string & sj = svec[j];
  138.                 int d = distance(svec, i, j, word_len);
  139.                 if(d == 1)
  140.                 {
  141.                     connect(G, edges, i, j);
  142.                 }
  143.             }
  144.         }
  145.  
  146.  
  147.         return bfs(G, start_pos, end_pos);
  148.     }
  149.  
  150.     int bfs(graph_t & G, int start, int end)
  151.     {
  152.         std::deque<int> Q;
  153.         std::deque<int> Depth;
  154.  
  155.         std::unordered_set<int> visited;
  156.  
  157.         Q.push_back(start);
  158.         Depth.push_back(1);
  159.  
  160.         while(!Q.empty())
  161.         {
  162.             int vertex = Q.front();                    
  163.             int depth = Depth.front();
  164.  
  165.             Q.pop_front();
  166.             Depth.pop_front();
  167.  
  168.             if(vertex == end) { return depth; }
  169.  
  170.             if(visited.find(vertex) != visited.end()) { continue; }
  171.  
  172.             visited.insert(vertex);
  173.  
  174.             graph_t::iterator it = G.find(vertex);
  175.             if(it == G.end()) { continue; }
  176.             const std::vector<int> & siblings = it->second;
  177.             for(size_t i = 0; i < siblings.size(); ++i)
  178.             {
  179.                 Q.push_back(siblings[i]);
  180.                 Depth.push_back(depth+1);
  181.             }
  182.         }
  183.         return 0;
  184.     }
  185. };
Advertisement
Add Comment
Please, Sign In to add comment