127. 单词接龙

127. 单词接龙

题目描述

字典 wordList 中从单词 beginWordendWord转换序列 是一个按下述规格形成的序列:

  • 序列中第一个单词是 beginWord

  • 序列中最后一个单词是 endWord

  • 每次转换只能改变一个字母。

  • 转换过程中的中间单词必须是字典 wordList 中的单词。

给你两个单词 beginWordendWord 和一个字典 wordList ,找到从 beginWordendWord最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。

示例 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" 不在字典中,所以无法进行转换。

提示:

  • 1 ≤ b e g i n W o r d . l e n g t h ≤ 10 1 \le beginWord.length \le 10 1beginWord.length10
  • endWord.length == beginWord.length
  • 1 ≤ w o r d L i s t . l e n g t h ≤ 5000 1 \le wordList.length \le 5000 1wordList.length5000
  • wordList[i].length == beginWord.length
  • beginWord、endWord 和 wordList[i] 由小写英文字母组成
  • beginWord != endWord
  • wordList 中的所有字符串 互不相同

题解:

建图 + 广搜。

提前预处理出 beginWordwordList 中的每个字符串变换后下一个可能的字符串,并根据这个建图。BFS 找出 beginWordendWord 的最短路径即可。

时间复杂度: O ( n ∗ L 2 ) O(n * L^2) O(nL2)

额外空间复杂度: O ( n 2 ∗ L ) O(n^2 * L) O(n2L)

class Solution {
public:
    unordered_map<string, vector<string>> g;
    unordered_map<string, int> dis;
    unordered_set<string> cand;

    void getNexts( const string& st, const vector<string>& wordList ) {
        string s = st;
        for ( int i = 0; st[i]; ++i ) {
            for ( s[i] = 'a'; s[i] <= 'z'; ++s[i] ) {
                if ( s[i] != st[i] && cand.find( s ) != cand.end() ) 
                    g[st].emplace_back( s );
            }
            s[i] = st[i];
        }
        for ( const auto& it : wordList ) {
            s = it;
            for ( int i = 0; it[i]; ++i ) {
                for ( s[i] = 'a'; s[i] <= 'z'; ++s[i] ) {
                    if ( s[i] != it[i] && cand.find( s ) != cand.end() ) 
                        g[it].emplace_back( s );
                }
                s[i] = it[i];
            }
        }
    }

    int bfs( const string& st, const string& ed ) {
        queue<string> q;
        unordered_set<string> vis;
        q.push( st );
        dis[st] = 1;
        vis.insert( st );
        string now;
        while ( q.size() ) {
            now = q.front();
            q.pop();
            for ( const auto& it : g[now] ) {
                if ( vis.find( it ) != vis.end() ) continue;
                dis[it] = dis[now] + 1;
                if ( it == ed ) return dis[it];
                vis.insert( it );
                q.push( it );
            }
        }
        return 0;
    }

    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        for( const auto& it : wordList )
            cand.insert( it );
        if ( cand.find( endWord ) == cand.end() ) return 0;
        getNexts( beginWord, wordList );
        return bfs( beginWord, endWord );
    }
};
/*
时间:200ms,击败:51.20%
内存:30.8MB,击败:22.13%
*/

也可以直接广搜,不建图。

时间复杂度: O ( n ∗ L 2 ) O(n * L^2) O(nL2)

额外空间复杂度: O ( n ∗ L ) O(n * L) O(nL)

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> cand;
        unordered_map<string, int> dis;
        for( const auto& it : wordList )
            cand.insert( it );
        if ( cand.find( endWord ) == cand.end() ) return 0;
        queue<string> q;
        q.push( beginWord );
        dis[beginWord] = 1;
        
        string now, ans;
        while ( q.size() ) {
            now = q.front();
            q.pop();
            ans = now;
            for ( int i = 0; now[i]; ++i ) {
                for ( ans[i] = 'a'; ans[i] <= 'z'; ++ans[i] ) {
                    if ( ans[i] != now[i] && cand.find( ans ) != cand.end() ) {
                        if ( dis.count( ans ) ) continue;
                        dis[ans] = dis[now] + 1;
                        if ( ans == endWord ) return dis[ans];
                        q.push( ans );
                    }
                }
                ans[i] = now[i];
            }
        }
        return 0;
    }
};
/*
时间:128ms,击败:75.34%
内存:15.5MB,击败:36.19%
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单词接龙是一个游戏,旨在通过更改一个字母来逐步转换一个单词成为另一个指定的单词。规则包括: 1. 可用于接龙单词首字母必须与前一个单词的尾字母相同。 2. 当存在多个首字母相同的单词时,取长度最长的单词。如果长度也相等,则取词典序最小的单词。 3. 已经参与接龙单词不能重复使用。 对于给定的一组由小写字母组成的单词数组和指定的起始单词和结束单词,我们需要进行单词接龙,并输出最长的单词串,其中单词串是由单词拼接而成,中间没有空格。如果不存在这样的转换序列,则返回0。 例如,对于输入的例子 beginWord = "hit",endWord = "cog",wordList = ["hot", "dot", "dog", "lot", "log"],我们可以进行以下单词接龙序列: "hit" -> "hot" -> "dot" -> "dog" -> "cog"。在这个例子中,最长的单词串为"hit" -> "hot" -> "dot" -> "dog" -> "cog"。 请注意,以上例子只是为了说明单词接龙的概念和规则,并不是针对Python编程的具体实现。具体的实现方法可以使用广度优先搜索 (BFS) 或双向BFS等算法来解决。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python题目55:单词接龙](https://blog.csdn.net/m0_60741207/article/details/121528418)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [127. 单词接龙(Python)](https://blog.csdn.net/JulyLi2019/article/details/106610034)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值