LeetCode 127 — Word Ladder

Decimotercero y último problema del patrón Graphs — el Hard. Un grafo implícito: las palabras son nodos, conectados si difieren en una letra. BFS para shortest path sobre ese grafo.

Enunciado

Dadas beginWord, endWord y wordList, encuentra la longitud de la transformación más corta (cada paso cambia una letra y resulta en palabra de wordList). Devuelve 0 si imposible.

Ejemplo:

beginWord = "hit", endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
Output: 5  (hit → hot → dot → dog → cog)

Solución — BFS sobre grafo implícito + patrones wildcard

Truco: en lugar de comparar cada palabra con cada otra (O(N²·L)), agrupar palabras por patrones wildcard:

"hot" → patrones "*ot", "h*t", "ho*". Dos palabras conectadas si comparten algún patrón wildcard.

from collections import defaultdict, deque
 
class Solution:
    def ladderLength(self, beginWord, endWord, wordList):
        if endWord not in wordList:
            return 0
 
        # Construir mapa pattern → lista de palabras
        L = len(beginWord)
        patterns = defaultdict(list)
        for word in wordList:
            for i in range(L):
                pattern = word[:i] + '*' + word[i+1:]
                patterns[pattern].append(word)
 
        # BFS
        q = deque([(beginWord, 1)])
        visited = {beginWord}
        while q:
            word, level = q.popleft()
            if word == endWord:
                return level
            for i in range(L):
                pattern = word[:i] + '*' + word[i+1:]
                for nb in patterns[pattern]:
                    if nb not in visited:
                        visited.add(nb)
                        q.append((nb, level + 1))
        return 0

Análisis: O(N · L²) tiempo (N palabras × L posiciones × L para construir pattern).

Por qué patterns wildcards

Sin ellos, comparar cada par de palabras letra a letra es O(N² · L). Con patterns, agrupamos palabras conectadas en O(N · L) y consultamos vecinos en O(1) amortizado.


Cierre del patrón Graphs

#ProblemaIdea distintiva
1200-number-of-islandsDFS en grid + componentes
2133-clone-graphDFS + hash map para deep copy
3695-max-area-of-islandDFS devuelve área
4417-pacific-atlantic-water-flowDFS desde bordes (inverso)
5130-surrounded-regionsDFS desde bordes + flip
6994-rotting-orangesMulti-source BFS con tiempo
7286-walls-and-gatesMulti-source BFS para distancias
8207-course-scheduleDFS con 3 colores o Kahn
9210-course-schedule-iiTopological sort completo
10684-redundant-connectionUnion-Find básico
11323-number-of-connected-components-in-an-undirected-graphDFS o UF para componentes
12261-graph-valid-treeUF + check de aristas
13EsteBFS shortest path sobre grafo implícito

Próximo patrón: Advanced Graphs (6 problemas: Dijkstra, MST, etc.).


Conexiones

Estado

  • Leído
  • Implementado desde cero
  • Resuelto en LeetCode
  • Patrón Graphs cerrado [OK]