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.
题意是:给出两个字符串start和end以及一个字符串集合dict,要求从start变换到end所需的最小步骤。变换规则是:每次只能改变字符串中的一个字符,而且改变后形成的新的字符串要是字典dict中的字符串。

刚看这题可能没有思路,但是把变换过程在纸上画画之后就明白怎么做了。以下是题目的抽象图。


即从图上找寻从起始节点到目标节点的最短路径问题。这是图的遍历问题,使用的方法无非BFS和DFS,要找最短路径,DFS只会一路到底,无疑BFS最合适。用BFS遍历图,一旦碰到目标节点即退出,此时路径即是最短路径。

注意:

(1)BFS搜索应该用队列来模拟;

(2)应该用一个数组类型的数据结构来记录已被遍历的节点,为求速度,可以使用unordered_set或set(竟然会超时可怜);

(3)遍历时,应该将与某个节点相邻的未访问节点push进队列中,但怎么知道两个节点相邻?一个个搜索比较会超时,网上有一种很巧妙的方法,即依次将节点string的第i位变换(26次)然后在字典中查找变换后的节点是否在字典中(用的unordered_set数据结构,查找时间为常数),相同的话push进队列;

(4)节点不仅要记录string,还要记录其在遍历中是第几步,应该用一个struct封装;

好了上代码:

class Solution {
public:
	struct Node{
		string str;
		int count;
		Node(string s, int n) :str(s), count(n){}
	};
public:
	int ladderLength(string start, string end, unordered_set<string> &dict) 
	{
		if (start == end)
			return 1;
		if (isNeibours(start, end))
			return 2;
		visited.clear();
		while (!que.empty())
			que.pop();
		que.push(Node(start, 1));
		int res = 0;
		while (!que.empty())
		{
			Node NowNode(que.front());
			if (isNeibours(NowNode.str, end))
			{
				res = NowNode.count + 1;
				break;
			}
			que.pop();
			for (int i = 0; i < NowNode.str.size(); ++i)
			{
				for (int j = 0; j < 26; ++j)
				{
					string temp = NowNode.str;
					temp[i] = 'a' + j;
					if (temp != NowNode.str && dict.find(temp) != dict.end() && visited.find(temp) == visited.end())
					{
						que.push(Node(temp,NowNode.count+1));
						visited.insert(temp);
					}	
				}
			}
		}
		return res;
	}
private:
	bool isNeibours(string s1, string s2)
	{
		int count = 0;
		for (int i = 0; i < s1.size(); ++i)
		{
			if (s1[i] != s2[i])
				++count;
			if (count > 1)
				return false;
		}
		return true;
	}
private:
	unordered_set<string> visited;
	queue<Node> que;
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章