LeetCode OJ Word Ladder II

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.
看了Discuss里面的题解, https://leetcode.com/discuss/9523/share-two-similar-java-solution-that-accpted-by-oj

自己改成了C++版本,具体的思路就是把每个string当做一个点,先BFS找到边,然后DFS找路径,感觉有点像某道什么素数路径的题。

class Solution {
public:
	vector<vector<string> > ans;  // answer
	vector<string> backtraceList;  //  list for backtracing, maybe an answer
	map<string, vector<string> > edges;  // treat every string as a point
	string st;  // start string
	string ed;  // end string
	unordered_set<string> visit;  // BFS visit
	unordered_set<string> unvisit;  // BFS unvisit
	vector<vector<string>> findLadders(string start, string end, unordered_set<string> & dict) {
		ans.clear();
		backtraceList.clear();
		edges.clear();
		if (dict.size() == 0) return ans;
		st = start;
		ed = end;
		visit.clear();
		unvisit = dict;
		BFS();  // bfs makes graph
		DFS(ed);  // dfs find roads(from end to start)
		return ans;
	}
	void BFS() {
		int cur = 1;  // current points to check
		int next = 0;  // next points to check
		int l;  // the length of each word
		bool found = false;
		queue<string> q;
		q.push(st);
		unvisit.insert(ed);
		unvisit.erase(st);  // maybe there is another start string in the dict

		while (!q.empty()) {
			string w = q.front();
			q.pop();
			cur--;
			l = w.size();
			for (int i = 0; i < l; i++) {
				char originalChar = w[i];
				string nw = w;
				for (char c = 'a'; c <= 'z'; c++) {
					nw[i] = c;
					if (unvisit.find(nw) != unvisit.end()) {  // an unvisited word
						if (visit.find(nw) == visit.end()) {  // there is no this word in visit
							visit.insert(nw);
							next++;  // more word to visit next time
							q.push(nw);
						}
						map<string, vector<string> >::iterator iter = edges.find(nw);
						if (iter != edges.end()) {  // a new point of an existed edge
							(*iter).second.push_back(w);
						}
						else {  // a new edge
							vector<string> temp;
							temp.push_back(w);
							edges[nw] = temp;
						}
						if (nw == ed) found = true;
					}
				}
				w[i] = originalChar;
			}
			if (cur == 0) {
				if (found) break;
				cur = next;
				next = 0;
				unordered_set<string>::iterator iter = visit.begin();
				for (; iter != visit.end(); iter++) unvisit.erase(*iter);
				visit.clear();
			}
		}
	}
	void DFS(string w) {
		if (w == st) {  // find start string
			vector<string> temp;
			temp.push_back(st);
			for (int i = 0, s = backtraceList.size(); i < s; i++)
				temp.push_back(backtraceList[s - i - 1]);
			ans.push_back(temp);
			return;
		}
		backtraceList.push_back(w);
		map<string, vector<string> >::iterator iter = edges.find(w);
		if (iter != edges.end()) {
			int s = iter->second.size();
			for (int i = 0; i < s; i++) DFS(iter->second[i]);
		}
		backtraceList.pop_back();
	}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值