leecode 解题总结:127. Word Ladder

#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <queue>
#include <unordered_map>
using namespace std;
/*
问题:
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

Only one letter can be changed at a time.
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
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.
You may assume no duplicates in the word list.
You may assume beginWord and endWord are non-empty and are not the same.

分析:这是求最短字符串长度。广度优先搜索用于求解最优问题。
可以使用广度优先搜索,设定每个字符串到初始字符串的距离。
根据当前遍历的字符串,找到其所有变位词,遍历变位词,如果变位词的距离已经被设置了
则跳过(说明该单词之前被访问过,不可能在一个里面出现重复的变位词),
如果没有访问过,获取当前单词距离,设置变位词的距离=当前单词距离+1

输入:
hit cog 6
hot dot dog lot log cog
hit cog 5
hot dot dog lot log
输出:
5
0
*/

class Solution {
public:

	vector<string> getOneEditWords(string& word , unordered_map<string,int>& words , unordered_map<string , vector<string> >& wordToNextWords)
	{
		vector<string> nextWords;
		if(word.empty())
		{
			return nextWords;
		}
		if(1 == wordToNextWords.count(word))
		{
			return wordToNextWords[word];
		}
		int len = word.length();
		char temp;
		for(int i = 0; i < len ; i++)
		{
			temp = word.at(i);
			for(char ch = 'a' ; ch <= 'z' ; ch++)
			{
				word.at(i) = ch;
				if(1 == words.count(word))
				{
					nextWords.push_back(word);
				}
				word.at(i) = temp;
			}
		}
		wordToNextWords[word] = nextWords;
		return nextWords;
	}

	int bfs(string beginWord, string endWord , vector<string>& wordList , 
		unordered_map<string,int>& words , unordered_map<string , vector<string> >& wordToNextWords)
	{
		unordered_map<string ,int> strToDistance;
		queue<string> queueWords;
		queueWords.push(beginWord);
		strToDistance[beginWord] = 0;
		vector<string> nextWords;
		string word;
		string nextWord;
		int curDistance = 0;
		int size;
		bool isFind = false;
		while(!queueWords.empty())
		{
			word = queueWords.front();
			queueWords.pop();
			nextWords = getOneEditWords(word ,words , wordToNextWords);
			if(nextWords.empty())
			{
				continue;
			}
			curDistance = strToDistance[word];
			size = nextWords.size();
			for(int i = 0 ; i < size ; i++)
			{
				nextWord = nextWords.at(i);
				//如果没有访问过
				if(strToDistance.find(nextWord) == strToDistance.end())
				{
					strToDistance[nextWord] = curDistance + 1;
					queueWords.push(nextWord);
					if(nextWord == endWord)
					{
						isFind = true;
					}
				}
			}
			if(isFind)
			{
				break;
			}
		}
		if(isFind)
		{
			return (curDistance + 2);//curDistance需要加上从当前字符串到结尾字符串的距离1,以及多1个元素
		}
		else
		{
			return 0;
		}
	}

    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        if(beginWord.empty() || endWord.empty() || wordList.empty())
		{
			return 0;
		}
		unordered_map<string , int> words;
		int size = wordList.size();
		for(int i = 0; i < size ; i++)
		{
			words[ wordList.at(i) ] = 1;
		}
		unordered_map<string , vector<string> > wordToNextWords;
		int result = bfs(beginWord, endWord , wordList , words , wordToNextWords);
		return result;
    }
};


void process()
{
	 vector<string> nums;
	 string value;
	 int num;
	 Solution solution;
	 string beginWord;
	 string endWord;
	 vector<vector<string> > result;
	 while(cin >> beginWord >> endWord >> num )
	 {
		 nums.clear();
		 for(int i = 0 ; i < num ; i++)
		 {
			 cin >> value;
			 nums.push_back(value);
		 }
		 int distance = solution.ladderLength(beginWord , endWord , nums);
		 cout << distance << endl;
	 }
}


int main(int argc , char* argv[])
{
	process();
	getchar();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值