127. 单词接龙(Hard)/ 126. 单词接龙 II(Hard)/ 472. 连接词(Hard)

这篇博客深入探讨了如何使用广度优先遍历(BFS)解决单词接龙问题,并介绍了优化策略——双向BFS,以找到两个单词间的最短转换路径。通过实例解析了算法的实现细节,包括路径剪枝和字典优化,旨在提高搜索效率。此外,还介绍了相关的编程题目,如472.连接词,进一步阐述了这类问题的解决思路。

在这里插入图片描述

class Solution:
	# 广度优先遍历
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
        if endWord not in wordList:
            return 0

        wordList = set(wordList)
        queue = [(beginWord, 1)]
        
        while queue:
            curWord, level = queue.pop(0)

            if curWord == endWord:
                return level
            
            for i in range(len(curWord)):
                for j in 'abcdefghijklmnopqrstuvwxyz':
                    word = curWord[:i] + j + curWord[i+1:]
                    
                    if word in wordList:
                        wordList.remove(word)
                        queue.append((word, level + 1))
        
        return 0

126. 单词接龙 II

在这里插入图片描述

class Solution:
	# 双向BFS
    def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:
        wordList = set(wordList)  # 转换为hash实现O(1)的in判断
        if endWord not in wordList:
            return []

        # 分别为答案,用于剪枝的已访问哈希,当前的前向分支以及后向分支中的路径和的长度
        res, visited, length = [], set(), 2
        # 前向分支和后向分支
        # 前向路径分支与后向路径分支的字典结构为{结束词:到达该结束词的路径列表}
        forward, backward = {beginWord: [[beginWord]]}, {endWord: [[endWord]]}
        while forward:
            if len(forward) > len(backward):  # 始终从路径分支较少的一端做BFS
                forward, backward = backward, forward
                
            tmp = {}  # 存储新的前向分支
            while forward:
                word, paths = forward.popitem()  # 取出路径结束词以及到达它的所有路径
                visited.add(word)  # 记录已访问
                for i in range(len(word)):
                    for c in 'abcdefghijklmnopqrstuvwxyz':
                        new = word[:i] + c + word[i+1:]  # 对结束词尝试每一位的置换
                        if new in backward:  # 如果在后向分支列表里发现置换后的词,则路径汇合
                            if paths[0][0] == beginWord:  # 前向分支是从beginWord开始的,添加路径会和的笛卡尔积
                                res.extend(fPath + bPath[::-1] for fPath in paths for bPath in backward[new])
                            else:  # 后向分支是从endWord开始的,添加路径会和的笛卡尔积
                                res.extend(bPath + fPath[::-1] for fPath in paths for bPath in backward[new])
                        if new in wordList and new not in visited:  # 仅当wordList存在该词且该词还未碰见过才进行BFS
                            tmp[new] = tmp.get(new, []) + [path + [new] for path in paths]
            length += 1

            if res and length > len(res[0]):  # res已有答案,且下一次BFS的会和路径长度已超过当前长度,不是最短
                break
            forward = tmp  # 更新前向分支

        return res

472. 连接词

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值