127_Word Ladder

本文深入探讨了从一个单词通过更改一个字符至另一个单词的最短路径问题,采用广度优先搜索(BFS)算法实现,详细解释了算法原理及代码实现过程。

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

题目

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.
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.
Example 1:

Input:
beginWord = “hit”,
endWord = “cog”,
wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]

Output: 5

Explanation: As one shortest transformation is “hit” -> “hot” -> “dot” -> “dog” -> “cog”,
return its length 5.
Example 2:

Input:
beginWord = “hit”
endWord = “cog”
wordList = [“hot”,“dot”,“dog”,“lot”,“log”]

Output: 0

Explanation: The endWord “cog” is not in wordList, therefore no possible transformation.

怎么搞呢
  1. 需要单词一个一个字符改变?

    可以循环解决:第一层循环:遍历单词第一个字符到最后一个字符,
    第二层循环:修改当前字符的,从a->z
    查找字典里有没有修改后的字母,有的话跳出,进行下一轮查找

  2. 网上说要使用 BFS 广度优先遍历,why?

    字典里找单词,怎么就成广度优先搜索了?

    这种情况使用BFS呢? 理解不了啊???

    再想想 BFS的经典套路,就是二叉树的层序遍历,遍历到第一个叶子结点,那么它的深度 也就是树的到叶子结点的最短深度

    现在要求的是也最短路径,遍历到第一个结果–》成功到达目标字符串,就是最短路径? 从例子看起:

    beginWord = “aot”,
    endWord = “cog”,
    wordList = [“hot” “got” “god” “cod” “cog”]

    amazing? 想一想,再想一想,emmmmm, hit 到 cog, 先将hit ,"" (空字符串)压入队列,这是零层,
    “” (空字符串)是每层的分隔字符串

    队列入队列层数
    ithot got “”一层
    ot无入队
    otgod cod “”二层
    odcod上一个已经被删了,所以这一波,无入队
    odcog,最终结果,bingo~三层

    这一波下来,不就是 广度优先搜索遍历么,层序遍历有木有, 其实我觉得自己想还是挺难想到的,代码里while中的两层for循环挺重要,每一波循环相当于把每一个位置上,修改一个字符且存在于字典的 单词都给放入的队列里。

class Solution {
public:
    int ladderLength(string start, string end, vector<string>& wordList) {
        unordered_set<string> dict(wordList.begin(), wordList.end());
        if (0 == start.size() || 0 == end.size()) return 0;
        if(dict.find(end) == dict.end()) return 0;
        queue<string> wordQ;
        wordQ.push(start);  // 先进先出   每一个单词 用""空字符串分隔
        wordQ.push("");
        int Path = 1;

        // 这样一波,怎么就保证是最短路径了?  
        //
        while (!wordQ.empty()) {
          string str = wordQ.front();
          wordQ.pop();

          if (str != "") {
            int len = str.size();
            // 这每一波循环,相当于把每一个位置上,修改一个字符且存在于字典的 单词都给放入的队列里
            for (int i = 0; i < len; i++) {
              char tmp = str[i];  //保存要修改的字符

              for (char c = 'a'; c <= 'z'; c++) {
                if (c == tmp)
                  continue;
                str[i] = c;
                if (str == end)
                  return Path + 1;
                if (dict.find(str) != dict.end()) {
                  wordQ.push(str);
                  dict.erase(str); // 一个单词只能用一次
                }
              }
              str[i] = tmp; //恢复要修改的字符
            }
          } else if (!wordQ.empty()) {
            Path++;
            wordQ.push("");
          }
        }
        return 0;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值