【LeetCode】127. Word Ladder

Difficulty: Medium

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence frombeginWord to endWord, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["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.
算法思路:

1.因为首单词和尾单词都没有加入wordList当中,所以先加入尾单词到wordList当中

2.从beginWord开始,进行广度优先搜索,每相邻的两个节点表示只有一个字母不同,进行BFS的关键问题在于如何做到不超时,这道题的做法就是不建图,因为建图的时间复杂度为O(n*n),如果n比较大的时候是会超时的,所以BFS的每条边都是把字符串的每个字母从‘a’到‘z’遍历,所以时间复杂度为O(sizeOfByte * 26)

3.在BFS的过程当中,一旦找到了endWord就立刻返回最短路径

但是按照这样的思路,我还是超时,因为这道题还有需要注意的点:

学会利用unordered_set,一开始我使用map来标记每个节点有没有访问过,然后也是超时,结果在网上看到别人通过的基本上都是利用了unordered_set,每次查找都是O(1)的时间复杂度,然后访问过的节点直接删掉就行了,所以我查了一下unordered_set


C++程序设计语言中,unordered_map、unordered_multimap、unordered_set、unordered_multiset是标准模板库(STL)提供的一类无序关联容器(unordered associative containers)。是通过哈希表实现的数据结构。无序是指元素的名字(或者键值)的存储是无序的;这与用平衡二叉树实现的元素名字是有序存储的“关联容器”是相对概念。所以通常比二叉树的存储方式可以提供更高的访问效率。

代码如下,时间复杂度为O(n * sizeOfByte * 26),n为单词的个数

class Solution {
public:
int BFS(unordered_set<string>& wordList, string& ta, string& tb)
{
	queue<string> path;
	queue<pair<string, int > > q;
	q.push(make_pair(ta, 0));
	while (!q.empty())
	{
		pair<string, int > entry = q.front();
		q.pop();
		for (int i = 0; i < (int)entry.first.size(); i++)
		{
			for (int j = 0; j < 26; j++)
			{
				char bit = 'a' + j;
				if (entry.first[i] == bit)	continue;
				else {
					string newstr = entry.first;
					newstr[i] = bit;
					unordered_set<string>::iterator exist = wordList.find(newstr);
					if (exist != wordList.end() )
					{
						int newpath = entry.second+1;
						q.push(make_pair(newstr, newpath));
						if (newstr == tb) {
							return newpath + 1;
						}
						wordList.erase(newstr);
					}
				}
			}
		}

		
	}
	return 0;

	
}

int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList)
{
	if (beginWord.size() == 0 || endWord.size() == 0 || beginWord.size() != endWord.size() || beginWord == endWord)
		return 0;
	wordList.insert(endWord);
	//map<string, int> exist;
	
	int res = BFS(wordList, beginWord, endWord);
	return res;

}
};



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值