给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。
说明:
如果不存在这样的转换序列,返回 0。
所有单词具有相同的长度。
所有单词只由小写字母组成。
字典中不存在重复的单词。
你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
示例 1:
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
输出: 5
解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
返回它的长度 5。
示例 2:
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
输出: 0
解释: endWord "cog" 不在字典中,所以无法进行转换。
解题思路:
广度优先搜索,先判断字符数组中是否有endword,若没有则返回0,若有,则进行判断。
在字符数组中进行优先搜索,以数组模拟队列,先将beginword入队,再在字符数组中进行搜索,若搜索得到与beginword只有一个字符差别的字符串,则将该字符串入队,然后依次搜索入队的字符串,同样的搜索与之相差一个字符的字符串入队,直到搜索到endword为止。
代码实现:
#define maxsize 10000
bool compare(char* a, char* b) //定义一个比较函数,比较字符串a和b是否只有一个字符不同
{
int i;
int count = 0;
for (i = 0; i < strlen(a); i++)
{
if (a[i] != b[i])
{
count++;
}
}
if (count == 1)
{
return true;
}
else
{
return false;
}
}
int ladderLength(char * beginWord, char * endWord, char ** wordList, int wordListSize)
{
char* Queue[maxsize] = {0}; //申请一个数组模拟队列
int* visited = (int*)calloc(wordListSize, sizeof(int)); //定义辅助数组
int head = 0; //头指针
int tail = 0; //尾指针
int deep = 1; //保存最短路径
for (int i = 0; i < wordListSize; i++) //判断字符串数组中是否有目标字符串
{
if (strcmp(endWord, wordList[i]) == 0)
{
break;
}
if (i == wordListSize - 1)
{
return 0;
}
}
Queue[tail++] = beginWord; //入队
while (head < tail) //若队列不为空
{
int size = tail - head; //当前层个数
for (int j = 0; j < size; j++) //遍历当前层
{
char* cur = Queue[head++]; //首字符串出队
if (strcmp(cur, endWord) == 0) //若为目标字符串则返回结果
{
return deep;
}
for (int k = 0; k < wordListSize; k++) //遍历字符串寻找与当前字符串相差一个字符的字符串,若没有遍历过,则入队
{
if (visited[k] == 0 && compare(cur, wordList[k]))
{
visited[k] = 1;
Queue[tail++] = wordList[k];
}
}
}
deep++; //路径加一
}
free(visited);
return 0;
}