[leetcode] Word Ladder

本文探讨了从一个单词通过一系列转换到达另一个单词的问题,并给出了使用BFS算法实现的具体代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.
可以把这道题变成一个搜索单源最短路径的问题。利用DFS搜索

class Solution {
public:
    int ladderLength(string start, string end, unordered_set<string> &dict) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		dict.erase(start);
		dict.erase(end);
		vector<string> words;
		words.push_back(start);
		words.insert(words.end(),dict.begin(),dict.end());
		words.push_back(end);
		int length=words.size();
		int wordlength=start.size();
		int count,min=INT_MAX;
		bool *flag=new bool[length];
		memset(flag,false,sizeof(bool)*length);
		int (*graph)[10000]=new int[length][10000];
		for(int i=0 ; i<length ; i++){
			graph[i][i]=0;
			for(int j=i+1 ; j<length ; j++){
				count=0;
				for(int k=0 ; k<wordlength ; k++){
					if(words[i][k]!=words[j][k])
						count++;
				}
				graph[i][j]=count;
				graph[j][i]=count;
			}
		}//form the graph;
		count=1;
		flag[0]=true;
		DFS(graph,0,length-1,flag,length,count,min);
		return min==INT_MAX?0:min;
	}
	void DFS(int (*g)[10000], int i, const int j, bool *flag, int n, int& count, int& min){
		if(i==j){
			if(count<min)
				min=count;
			return;
		}
		for(int k=0 ; k<n ; k++){
			if(g[i][k]==1 && !flag[k]){
				flag[k]=true;
				count++;
				DFS(g,k,j,flag,n,count,min);
				count--;
				flag[k]=false;
			}
		}
	}
};
但是过不了大数据,把DFS改成BFS试试。
class Solution {
    typedef pair<int,int> path;
public:
	int ladderLength(string start, string end, unordered_set<string> &dict) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		dict.erase(start);
		dict.erase(end);
		vector<string> words;
		words.push_back(start);
		words.insert(words.end(),dict.begin(),dict.end());
		words.push_back(end);
		int length=words.size();
		int wordlength=start.size();
		int count,min=INT_MAX;
		bool *flag=new bool[length];
		memset(flag,false,sizeof(bool)*length);
		int (*graph)[10000]=new int[length][10000];
		for(int i=0 ; i<length ; i++){
			graph[i][i]=0;
			for(int j=i+1 ; j<length ; j++){
				count=0;
				for(int k=0 ; k<wordlength ; k++){
					if(words[i][k]!=words[j][k])
						count++;
				}
				graph[i][j]=count;
				graph[j][i]=count;
			}
		}//form the graph;
		queue<pair<int,int> > bfs;
		bfs.push(make_pair(0,1));
		while(!bfs.empty()){
			path head=bfs.front();
			flag[head.first]=true;
			if(head.first==length-1)
				return head.second;
			for(int i=0 ; i<length ; i++){
				if(graph[head.first][i]==1 && !flag[i])
					bfs.push(path(i,head.second+1));
			}
			bfs.pop();
		}
		if(bfs.empty())
			return 0;
	}
};

我的这种先弄一个二维矩阵的方法好像不被允许,提示内存超了。主要的时间耗费在了前面矩阵赋值上面,那么就不要先计算出这种矩阵,边BFS边比较:
class Solution {
public:
	int ladderLength(string start, string end, unordered_set<string> &dict) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		//BFS(because all edge is 1) to find the minimum path
		//O(n*len*26)
		queue<pair<string,int>> q;
		unordered_set<string> visited;
		q.push(make_pair(start, 1));
		visited.insert(start);
		while (!q.empty())	{
			string curStr = q.front().first;
			int curStep = q.front().second;
			q.pop();
			for (int i = 0; i < curStr.size(); ++i)	{
				string tmp = curStr;
				for (int j = 0; j < 26; ++j) {
					tmp[i] = j+'a';
					if(tmp == end)
						return curStep+1;
					if(visited.find(tmp) == visited.end() && dict.find(tmp) != dict.end()) {
						q.push(make_pair(tmp, curStep+1));
						visited.insert(tmp);
					}
				}
			}
		}
		return 0;
	}
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值