leetcode刷题_OJ 127

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.
题目的主要意思:

给出单词的开始形态和最终形态,要求从所给列表中找出最短的变化过程的次数,注意每次只能改变一个字母

一开始我的思路比较简单,最粗暴的BFS,直接两个队列,一个存放正在遍历的单词,另一个存放遍历完毕的单词。队列内的元素以键值对的形式存储,主要是<string,int><单词,代表所在层数>。当正在遍历的队列不为空时,取出其内的front元素的first即为单词,用26个字母依次对单词内的各个字母进行替换,如果此时替换得到的新单词等于目标单词,则返回当前层数。否则判断该新单词是否已经在列表内并且未被访问,若是,将其插入正在访问列表,并且标志气已访问。

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> dict(wordList.cbegin(), wordList.cend());
        queue<pair<string,int>> que;
        que.push(make_pair(beginWord,1));//储存单词以及出现的层数
        unordered_set<string> visited;
        visited.insert(beginWord);//存放以及遍历的节点
        bool flag=false;
        while(!que.empty()){
            pair<string,int> current=que.front();
            que.pop();
            string word=current.first;
            int len=word.size();
            for(int i=0;i<len;i++){
                string newWord(word);
                for(int j=0;j<26;j++){
                    newWord[i]='a'+j;
                    if(newWord == endWord){
                        flag=true;
                        return current.second+1;
                    }
                    //判断是否位于字典中并且是否被访问过
                    if(dict.count(newWord) > 0 && visited.count(newWord) == 0){
                        que.push(make_pair(newWord,current.second+1));
                        visited.insert(newWord);
                    }

                }
            }
        }
        //if(!flag){
            return 0;
        //}
        
    }
};

但是一直报个什么类型错误?理解不了,去参观大佬的做法后选择了一个优化的bfs,采用将数据分成两组来处理,哪组数据量少就处理哪组,任意一组为空则跳出循环。其它部分差不多

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> dict(wordList.cbegin(), wordList.cend());
        if(dict.count(endWord)) dict.erase(endWord);
        else return 0;
        unordered_set<string> phead, ptail;
        phead.insert(beginWord);
        ptail.insert(endWord);
        int len=beginWord.size(),count=2;//包括begin和end,所以是2
        while(!phead.empty() && !ptail.empty()){
            if(phead.size() > ptail.size()){//选择数据量少的来处理
                phead.swap(ptail);
            }
            unordered_set<string> tmp;
            for(auto item:phead){
                for(int i=0;i<len;i++){
                    char c=item[i];//保存现场
                    for(int j='a';j<='z';j++){//依次对每个单词的每位进行替换
                        item[i]=j;
                        if(ptail.count(item)) return count;
                        if(dict.count(item)){
                            tmp.insert(item);
                            dict.erase(item);
                        }
                    }
                    item[i]=c;//恢复现场
                }
            }
            phead.swap(tmp);
            count++;
        }
        return 0;    
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值