首页 > 试题广场 >

牛群最短移动序列

[编程题]牛群最短移动序列
  • 热度指数:322 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
在一个牛群中,每头牛都有一个编号,编号由小写字母组成,长度相同。牛群中的每头牛都有一个目标编号,当牛群中的一头牛移动到一个新的位置时,它的编号会发生改变,每次移动只能改变一个字母。现在给定一个表示牛群初始状态的编号 beginWord,一个表示牛群最终目标状态的编号 endWord,以及一个包含所有可能的编号序列的字典 wordList。请找出从 beginWord 到 endWord 的最短移动序列中的编号数目。如果不存在这样的移动序列,返回 0。
示例1

输入

"eat","cow",["cat","cot","eaw","eaw","caw"]

输出

0

说明

列表中不存在"cow",无法转换
示例2

输入

"eat","cow",["cat","cot","cow","cet","ant","dog"]

输出

4

说明

eat->cat->cot->cow

备注:
1 <= beginWord.length <= 16
endWord.length == beginWord.length
1 <= wordList.length <= 2000
wordList[i].length == beginWord.length
beginWord、endWord 和 wordList[i] 由小写英文字母组成
beginWord != endWord
wordList 中的所有字符串互不相同
哈希+广度优先搜索
#include <string>
#include <vector>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param beginWord string字符串 
     * @param endWord string字符串 
     * @param wordList string字符串vector 
     * @return int整型
     */
    
    // 检测两个字符串有多少个不同的字符
    bool check(string str_1, string str_2)
    {
        if(str_1.size()!=str_2.size())
            return false;
        
        int len = str_1.size();
        int res = 0;
        for(int i=0; i<len; ++i)
        {
            if(str_1[i]!=str_2[i])
                ++res;
        }

        return res==1;
    }

    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        // write code here

        // 哈希 + 广度优先搜索
        unordered_set<string> u_s(wordList.begin(),wordList.end());

        if(u_s.count(endWord)==0)
            return 0;

        // 将u_s中与beginWord一样的字符串删除
        if(u_s.count(beginWord))
            u_s.erase(beginWord);

        queue<string> q;
        q.emplace(beginWord);

        while(!q.empty())
        {
            int len = q.size();
            ++ans;

            for(int i=0; i<len; ++i)
            {
                string str= q.front();
                q.pop();
                
                if(str==endWord)
                    return ans;
                    
                // 从字典中找到与q.front()一字之差的字符串
                for(auto it=u_s.begin(); it!=u_s.end(); )
                {
                    if(check(str, *it))
                    {
                        // 这里修改一下
                        q.emplace(*it);
                        it = u_s.erase(it);
                        // q.emplace(*it);
                        // // u_s中删除这个字符串,避免重复利用
                        // u_s.erase(it);
                        // // 这里需要将it重新定义为u_s.begin(),否则产生段错误,it都被删了哪还有it
                        // it = u_s.begin();
                        // continue;
                    }
                    else
                        ++it;
                }
            }
        }

        return 0;
    }

private:
    int ans = 0;
};


发表于 2024-05-11 17:14:24 回复(0)