class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
"""tc O(N* W*W) sc O(N*W*W) W: len(word) N: number of words in word list
1. preprocessing all string pattern with one character matches any char as hashmap {h*t: [hit,hot]}
2. start from biginWord do BFS, terminate untild find a pattern matches endWord
3. mark used word to avoid repeated transformation
"""
queue = collections.deque([(beginWord, 1)])
visited = set(beginWord)
wordSet = set(wordList)
while queue:
word, level = queue.popleft()
if word == endWord:
return dist
for i in range(len(word)):
for j in string.ascii_lowercase:
new_word = word[:i] + j + word[i+1:]
if new_word not in visited and new_word in wordSet:
queue.append((new_word, level+1))
visited.add(new_word)
return 0