Word Ladder

406 篇文章 0 订阅
406 篇文章 0 订阅

1,题目要求

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.

给定两个单词(beginWord和endWord)和一个字典的单词列表,找到从beginWord到endWord的最短变换序列的长度,这样:

  1. 一次只能更改一个字母。
  2. 每个转换后的单词必须存在于单词列表中。 请注意,beginWord不是转换后的单词。

注意:

  • 如果没有这样的转换序列,则返回0。
  • 所有单词都有相同的长度。
  • 所有单词仅包含小写字母字符。
  • 您可以假设单词列表中没有重复项。
  • 您可能认为beginWord和endWord是非空的并且不相同。

2,题目思路

对于这道题,要求将一个单词按照字典转化为另一个单词。

在这个单词转化为题上,有两个条件:首先,每次只能转换一个字符;其次,转换的单词必须要出现在给定的字典中。

在解决这个问题上,实际上这是一个BFS问题:
从beginWord出发,然后访问它的邻居——出现在dict中并且只改变一个字符的单词,然后,访问这些邻居中尚未访问的邻居,直到访问到endWord位置。

同时,BFS的解决上,我们可以从两端同时开始出发,同时从beginWord和endWord出发,当二者相遇,自然是找到了最终的结果。

3,代码实现

static auto speedup = [](){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return nullptr;
}();

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> dict(wordList.begin(),wordList.end()), head, tail, *pHead, *pTail;
        
        if(dict.find(endWord) == dict.end())    //没找到这个单词
            return 0;
        
        head.insert(beginWord);
        tail.insert(endWord);
        
        int ladder = 2;
        
        while(!head.empty() && !tail.empty()){
            //让pHead指向长度较小的set,用于遍历
            //让pTail指向长度较大的set,用于搜索
            if(head.size() < tail.size()){
                pHead = &head;
                pTail = &tail;
            }
            else{
                pHead = &tail;
                pTail = &head;
            }
            unordered_set<string> tmp;
            for(auto it = pHead->begin();it!=pHead->end();it++){
                string word = *it;
                for(int i = 0;i<word.size();i++){
                    //依次更改word中的字符,判断是否在dict中
                    char origin = word[i];
                    for(int j = 0;j<26;j++){
                        word[i] = 'a' + j;  //a~z
                        //两集合相遇,即找到了转换方法
                        if(pTail->find(word) != pTail->end())
                            return ladder;
                        //没相遇,但是当前单词在dict中,则将这个转换加入候选以供下一次寻找
                        if(dict.find(word) != dict.end()){
                            tmp.insert(word);
                            dict.erase(word);   //已经遍历过dict中的单词,需要删除
                        }
                     }
                    word[i] = origin;   //恢复,以供下一个字符变化的遍历
                }
            }
            ladder++;
            pHead->swap(tmp);   //swap是替换,将当期head换为tmp
        }
        return 0;
    }
};
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值