Word Ladder II

Q:

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) 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"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

 

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

A:

好吧,我承认我得到的是所有的可达路径,怎么找所有的最短路径我还得想想,当然从所有的可达路径里面去找还是能得到的,但是过于淳朴了点吧,再想想

关键是nm就3个字符串的测试例我都tle?我擦,nm我不就求了一个相互之间的距离构成个图吗,如果超过2我还直接退出了,用的了那么高的时间复杂度吗。非要用dp遍历所有a-z才行?如果字符串非常长这样不是会死的很惨?反正我是想不到更好的办法了。nm的word ladder I哥哥自己测就正确,一到leetcode得到的结果竟然全部都是2,真tm2死了,烦躁。关键是测试例都nm一样啊。还是相信自己吧!!就这样,这两道题如果想到了更好的办法再回来搞。

#include <stdio.h>
#include <iostream>
#include <tr1/unordered_set>
#include <vector>
#include <string>
using namespace std;
using namespace std::tr1;

#define MAX_DIS 0x7fffff
class Solution {
public:
  vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
    // Start typing your C/C++ solution below
    // DO NOT write int main() function
    GenerateGragh(start, end, dict);
    unordered_set<int> visited_nodes;
    visited_nodes.insert(0);
    return Dfs(0, 1, visited_nodes);
  }

 private:
  void GenerateGragh(const string& start, const string& end,
      unordered_set<string> &dict) {
    if (dict.find(start) != dict.end()) dict.erase(start);
    if (dict.find(end) != dict.end()) dict.erase(end);
    dises_.clear();
    nodes_.push_back(start);
    nodes_.push_back(end);
    for (unordered_set<string>::iterator iter = dict.begin(); iter != dict.end(); ++iter) {
      nodes_.push_back(*iter);
    }
    dises_.resize(nodes_.size());

    for (int i = 0; i < nodes_.size(); ++i) {
      for (int j = i + 1; j < nodes_.size(); ++j) {
        int dis = CalcDistance(nodes_[i], nodes_[j]);
        if (dis > 1) continue;
        dises_[i].push_back(NodeDistance(j, dis));
        dises_[j].push_back(NodeDistance(i, dis));
      }
    }
  }

  int CalcDistance(const string& src, const string& dst) {
    int dis = 0;
    for (int i = 0; i < src.length(); ++i) {
      if (src[i] != dst[i]) dis++;
      if (dis >= 2) return MAX_DIS;
    }
    return dis;
  }

  vector<vector<string> > Dfs(int node, int dst, unordered_set<int>& visited_nodes) {
    vector<vector<string> > results;
    for (int i = 0; i < dises_[node].size(); ++i) {
      if (visited_nodes.find(dises_[node][i].dst) != visited_nodes.end()) continue;
      if (dises_[node][i].dst == dst) {
        vector<string> result;
        result.push_back(nodes_[node]);
        result.push_back(nodes_[dst]);
        results.push_back(result);
        continue;
      }
      visited_nodes.insert(dises_[node][i].dst);
      vector<vector<string> > part_results = Dfs(dises_[node][i].dst, dst, visited_nodes);
      for (int j = 0; j < part_results.size(); ++j) {
        vector<string> result;
        result.push_back(nodes_[node]);
        result.insert(result.end(), part_results[j].begin(), part_results[j].end());
        results.push_back(result);
      }
      visited_nodes.erase(dises_[node][i].dst);
    }
    return results;
  }
  
 private:
  class NodeDistance {
   public:
    int dst;
    int dis;
    NodeDistance(int dst_idx, int distance):dst(dst_idx), dis(distance) {}
    friend bool operator < (const NodeDistance& src, const NodeDistance& dst) {
      return src.dis < dst.dis;
    }
    friend bool operator > (const NodeDistance& src, const NodeDistance& dst) {
      return src.dis > dst.dis;
    }
  };

  vector<vector<NodeDistance> > dises_;
  vector<string> nodes_;
};

int main(int argc, char **argv)
{
    Solution s;
    unordered_set<string> dict;
    /*
    string start = "hot";
    string end = "dot";
    dict.insert("hot");
    dict.insert("dot");
    dict.insert("dog");*/
    string start = "red";
    string end = "tax";
    dict.insert("ted");
    dict.insert("tex");
    dict.insert("red");
    dict.insert("tax");
    dict.insert("tad");
    dict.insert("den");
    dict.insert("rex");
    dict.insert("pee");
    vector<vector<string> > results;
    results = s.findLadders(start, end, dict);
    for (int i = 0; i < results.size(); ++i) {
        for (int j = 0; j < results[i].size(); ++j) {
            cout << results[i][j] << "\t";
        }
        cout << endl;
    }
    return 0;
}

 

 

 

 

 

posted @ 2013-07-02 00:36  dmthinker  阅读(138)  评论(0)    收藏  举报