Genomgång av svåra problem: Word Ladder II och Alien Dictionary
Ta er an två svåra problem från början till slut – word-ladder-II med BFS + backtracking och alien-dictionary med topologisk sortering – med en fullständig förklaring.
Genomgång av svåra problem: Word Ladder II och Alien Dictionary är en gratis lektion i DSA Interview Prep på CoddyKit. Detta är lektion 4 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för DSA Interview Prep, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i DSA Interview Prep innehåller totalt 4 lektioner.
Varför svåra problem är annorlunda
Svåra LeetCode-problem skiljer sig från medelsvåra problem på två viktiga sätt: (1) de kräver att ni kombinerar två eller fler algoritmiska tekniker, och (2) den optimala lösningen är ofta inte uppenbar enbart utifrån problemformuleringen – ni måste genomskåda ytbeskrivningen och se den underliggande graf- eller DP-strukturen. Word Ladder II och Alien Dictionary är klassiska svåra problem som återkommer i FAANG-intervjuer.
Arbetssättet för svåra problem är följande: försök inte se hela lösningen direkt. Dela i stället upp problemet i delproblem, identifiera strukturen i varje delproblem, lös dem var för sig och koppla sedan ihop dem. Detta modulära tänkande är nyckeln till att lösa svåra problem under press.
# Hard problem meta-strategy
strategy = [
'1. Read the problem 2x — hard problems often have subtle constraints',
'2. Model it as a known structure: graph? DP table? sorted order?',
'3. Break into sub-problems: separate the graph-building from the traversal',
'4. Solve sub-problems in order, verifying each before connecting',
'5. Handle the edge case where no solution exists (empty result, -1, [])',
'6. Optimise only after the correct but slow solution works',
]
print('Hard problem meta-strategy:')
for step in strategy:
print(f' {step}')Word Ladder II: Problemformulering
Word Ladder II (LeetCode 126): Givet ett startord, ett slutord och en ordlista ska ni hitta alla kortaste omvandlingssekvenser från start till slut. Vid varje steg ändras exakt ett tecken, och varje mellanliggande ord måste finnas i ordlistan. Detta är betydligt svårare än Word Ladder I (som bara hittar en kortaste väg), eftersom ni måste räkna upp alla optimala vägar.
Exempel: beginWord='hit', endWord='cog', wordList=['hot','dot','dog','lot','log','cog'] → [['hit','hot','dot','dog','cog'],['hit','hot','lot','log','cog']]. Båda har längden 5.
# Word Ladder II problem breakdown
begin_word = 'hit'
end_word = 'cog'
word_list = ['hot','dot','dog','lot','log','cog']
# What we need:
# 1. Build a graph: word -> set of words that differ by one character
# 2. BFS to find the MINIMUM number of steps (shortest path distance)
# 3. DFS/backtracking to enumerate ALL paths of that minimum length
# Key insight: BFS finds shortest distance; DFS reconstructs all shortest paths
# Two-phase approach:
print('Phase 1: BFS from begin_word to find min distance to each word')
print('Phase 2: DFS/backtrack from end_word using only edges that decrease distance')
print()
print(f'Input: {begin_word} -> {end_word}')
print(f'Word list: {word_list}')
print('Expected: [[hit,hot,dot,dog,cog],[hit,hot,lot,log,cog]]')Word Ladder II: BFS-fasen
I fas 1 kör ni BFS nivå för nivå från startordet. På varje nivå hittar ni alla grannar (ord som skiljer sig åt med ett tecken). Ni registrerar den nivå (avståndet från starten) där varje ord nås för första gången. Ni stannar INTE när ni når slutordet – ni fortsätter tills nivån där end_word hittades är avslutad, så att alla kortaste vägar utforskas.
Det är avgörande att ni bygger en parents-ordbok som mappar varje ord till mängden ord som kan föregå det i en kortaste väg. Det är den graf som används i fas 2 för backtracking.
from collections import defaultdict, deque
def find_parents(begin, end, word_set):
parents = defaultdict(set)
layer = {begin}
found = False
while layer and not found:
next_layer = set()
for word in layer:
for i in range(len(word)):
for c in 'abcdefghijklmnopqrstuvwxyz':
new_word = word[:i] + c + word[i+1:]
if new_word in word_set and new_word not in parents:
next_layer.add(new_word)
parents[new_word].add(word)
if new_word == end:
found = True
layer = next_layer
return parents if found else {}
words = {'hot','dot','dog','lot','log','cog'}
parents = find_parents('hit', 'cog', words)
print('Parents map (which words can precede each word):')
for word, preds in sorted(parents.items()):
print(f' {word}: {preds}')Word Ladder II: DFS-fasen med backtracking
I fas 2 använder ni DFS med backtracking från slutordet och följer parents-mappningen i omvänd riktning. Ni bygger vägar från slut till start och vänder sedan på dem. När ni når startordet har ni hittat en fullständig kortaste väg. Mappningen över föregångare garanterar att alla vägar som hittas har minimal längd – ni kan inte avvika till en längre väg.
Detta tvåfasiga arbetssätt (BFS för nivåer och DFS för återskapande av vägar) är standardlösningen och körs i O(n × L × 26) för BFS, där n = ordlistans storlek och L = ordlängden, samt i O(K × L) för DFS, där K = antalet kortaste vägar.
def find_ladders(beginWord, endWord, wordList):
word_set = set(wordList)
if endWord not in word_set:
return []
# Phase 1: BFS to build parents map
parents = defaultdict(set)
layer = {beginWord}
found = False
visited = {beginWord}
while layer and not found:
next_layer = set()
for word in layer:
for i in range(len(word)):
for c in 'abcdefghijklmnopqrstuvwxyz':
nw = word[:i] + c + word[i+1:]
if nw in word_set and nw not in visited:
next_layer.add(nw)
parents[nw].add(word)
if nw == endWord: found = True
visited |= next_layer
layer = next_layer
# Phase 2: DFS backtrack from endWord to beginWord
result = []
def dfs(word, path):
if word == beginWord:
result.append(path[::-1])
return
for parent in parents[word]:
dfs(parent, path + [parent])
dfs(endWord, [endWord])
return result
print(find_ladders('hit','cog',['hot','dot','dog','lot','log','cog']))Alien Dictionary: Problemformulering
Alien Dictionary (LeetCode 269): Givet en lista med ord som är sorterade lexikografiskt på ett främmande språk ska ni bestämma tecknens ordning i språket. Returnera teckenordningen som en sträng. Om ingen giltig ordning finns (på grund av motsägelser) ska ni returnera en tom sträng.
Exempel: ['wrt','wrf','er','ett','rftt'] → 'wertf'. Genom att jämföra intilliggande ord får vi: 't' < 'f' (från wrt jämfört med wrf), 'w' < 'e' (från wrt jämfört med er), 'r' < 't' (från er jämfört med ett) och 'e' < 'r' (från ett jämfört med rftt). Detta är en topologisk sortering av dessa ordningsbegränsningar.
words = ['wrt', 'wrf', 'er', 'ett', 'rftt']
# Compare adjacent pairs to extract ordering:
# wrt vs wrf: first diff at index 2: t < f (t comes before f)
# wrf vs er: first diff at index 0: w < e (w comes before e)
# er vs ett: first diff at index 1: r < t (r comes before t)
# ett vs rftt:first diff at index 0: e < r (e comes before r)
ordering_constraints = [
('t', 'f', 'from wrt vs wrf'),
('w', 'e', 'from wrf vs er'),
('r', 't', 'from er vs ett'),
('e', 'r', 'from ett vs rftt'),
]
print('Ordering constraints extracted from adjacent word pairs:')
for a, b, source in ordering_constraints:
print(f' {a} -> {b} ({source})')
print('\nThis is a directed graph: find topological order = alien alphabet order')Alien Dictionary: Bygga grafen
Det första steget är att extrahera begränsningar: jämför varje intilliggande ordpar, hitta det första tecknet som skiljer sig och lägg till en riktad kant från det mindre till det större tecknet. Om ett ord är prefix till nästa ord men längre (till exempel 'abc' före 'ab') är indata ogiltig – returnera omedelbart en tom sträng.
Alla tecken som förekommer i ordlistan är noder i grafen, även om de inte har några ordningsbegränsningar. Dessa isolerade noder kan placeras var som helst i den slutliga ordningen.
from collections import defaultdict
def build_alien_graph(words):
adj = defaultdict(set) # char -> set of chars that come after it
in_degree = {c: 0 for word in words for c in word}
for i in range(len(words) - 1):
w1, w2 = words[i], words[i+1]
min_len = min(len(w1), len(w2))
found_diff = False
for j in range(min_len):
if w1[j] != w2[j]:
if w2[j] not in adj[w1[j]]: # avoid duplicate edges
adj[w1[j]].add(w2[j])
in_degree[w2[j]] += 1
found_diff = True
break
if not found_diff and len(w1) > len(w2):
return {}, {} # invalid: 'abc' before 'ab'
return adj, in_degree
words = ['wrt', 'wrf', 'er', 'ett', 'rftt']
adj, in_degree = build_alien_graph(words)
print('Adjacency list (directed):', {k: list(v) for k, v in adj.items()})
print('In-degrees:', in_degree)Alien Dictionary: Topologisk sortering
När grafen har byggts tillämpar ni Kahns topologiska BFS-sortering: initiera en kö med alla tecken som har ingrad 0 (inga föregångare). Bearbeta varje tecken och minska ingraden för dess efterföljare. När en efterföljares ingrad når 0 lägger ni till den i kön. Samla tecknen i den ordning de bearbetas – detta är den främmande alfabetiska ordningen.
Om resultatet innehåller alla tecken har vi en giltig ordning. Om färre tecken än förväntat finns med innehåller grafen en cykel – begränsningarna motsäger varandra och vi returnerar en tom sträng.
from collections import deque, defaultdict
def alien_order(words):
adj = defaultdict(set)
in_degree = {c: 0 for word in words for c in word}
for i in range(len(words) - 1):
w1, w2 = words[i], words[i + 1]
min_len = min(len(w1), len(w2))
found = False
for j in range(min_len):
if w1[j] != w2[j]:
if w2[j] not in adj[w1[j]]:
adj[w1[j]].add(w2[j])
in_degree[w2[j]] += 1
found = True; break
if not found and len(w1) > len(w2):
return '' # invalid: 'abc' before 'ab'
# Kahn's BFS topological sort
queue = deque([c for c in in_degree if in_degree[c] == 0])
result = []
while queue:
c = queue.popleft()
result.append(c)
for neighbor in sorted(adj[c]): # sort for determinism
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.append(neighbor)
return ''.join(result) if len(result) == len(in_degree) else ''
print(alien_order(['wrt','wrf','er','ett','rftt'])) # e.g., 'wertf'
print(alien_order(['z','x'])) # 'zx'
print(alien_order(['z','x','z'])) # '' (cycle z->x->z)Hantera kantfall: Båda problemen
Både Word Ladder II och Alien Dictionary har subtila kantfall som orsakar felaktiga svar om de inte hanteras:
- Word Ladder II: beginWord och endWord är samma (returnera
[[beginWord]]eller en lista med längden 1). endWord finns inte i wordList (returnera tomt resultat). Ingen väg finns (returnera tomt resultat). - Alien Dictionary: duplicerade ord (extrahera ingen begränsning). Ett enda ord (returnera alla unika tecken). Cykel i begränsningarna (returnera ''). Ett ord är ett längre prefix till nästa ord (ogiltig indata, returnera ''). Alla tecken är isolerade (returnera valfri ordning).
# Edge case tests for Word Ladder II
def test_word_ladder_edge_cases():
from collections import defaultdict
def find_ladders(begin, end, word_list):
# [abbreviated implementation for testing]
if end not in word_list: return []
if begin == end: return [[begin]]
return [] # placeholder
tests = [
('hit', 'cog', ['hot','dot','dog','lot','log'], []), # no path (cog missing)
('hit', 'hit', ['hit'], [['hit']]), # begin==end
('a', 'c', ['a','b','c'], [['a','c']]), # short words
]
for begin, end, wl, expected in tests:
result = find_ladders(begin, end, wl)
print(f'{begin}->{end}: result={result}')
# Edge case tests for Alien Dictionary
def test_alien_edge_cases():
from collections import defaultdict, deque
# (using alien_order from previous scene)
tests = [
(['abc', 'ab'], ''), # 'abc' before 'ab' = invalid
(['a'], 'a'), # single word
(['z','z'], 'z'), # duplicate: no constraint
]
print('Alien dictionary edge cases:')
for words, expected in tests:
print(f' {words} -> expected: "{expected}"')
test_word_ladder_edge_cases()
test_alien_edge_cases()Komplexitetsanalys: Båda problemen
Komplexiteten för Word Ladder II: BFS-fasen körs i O(n × L × 26), där n = antalet ord i listan och L = ordlängden. För varje ord på varje BFS-nivå genererar vi 26L kandidatord och kontrollerar om de finns i mängden av ord (O(1) per kontroll). DFS-fasen körs i O(K × L), där K = antalet kortaste vägar (vilket i teorin kan vara exponentiellt).
Komplexiteten för Alien Dictionary: Att bygga grafen tar O(C), där C = det totala antalet tecken i alla ord. Den topologiska sorteringen tar O(V + E), där V = antalet unika tecken och E = antalet ordningsbegränsningar. Totalt blir det O(C), vilket är O(antalet tecken i indata).
# Complexity analysis for both problems
complexities = [
{
'problem': 'Word Ladder II',
'time': 'O(n * L * 26) BFS + O(K * L) DFS backtracking',
'space': 'O(n * L) for word set + parents map',
'notes': 'K (number of shortest paths) can be exponential in pathological cases',
},
{
'problem': 'Alien Dictionary',
'time': 'O(C) where C = total characters in all words',
'space': 'O(V + E) for adjacency list',
'notes': 'V <= 26 (alphabet), E <= V^2 = 676; often treated as O(C) total',
},
]
for c in complexities:
print(f'{c["problem"]}:')
print(f' Time: {c["time"]}')
print(f' Space: {c["space"]}')
print(f' Notes: {c["notes"]}')
print()Mönstersammanfattning: Två återanvändbara mallar
Båda problemen lär ut återanvändbara mönster. Word Ladder II = BFS för avstånd + DFS för återskapande av vägar: detta mönster används när ni behöver hitta alla kortaste vägar i en oviktad graf. Bygg mappningen över föregångare under BFS och backtracka sedan från målet till källan.
Alien Dictionary = extrahering av kanter + topologisk sortering: detta mönster används när ni får en sorterad sekvens och måste härleda de underliggande ordningsreglerna. Extrahera riktade begränsningar från intilliggande ordpar och tillämpa sedan Kahns algoritm. Returnera '' när en cykel upptäcks (ordningen är omöjlig).
# Pattern templates
print('Template 1: All Shortest Paths in Unweighted Graph')
template_1 = '''
1. BFS from source, recording parents[node] = set of nodes that lead to node
2. Continue each BFS level fully (do not stop at first endNode reach)
3. DFS backtrack from endNode, following parents map
4. Reverse each path found (built end->start, need start->end)
'''
print(template_1)
print('Template 2: Infer Ordering from Sorted Sequence')
template_2 = '''
1. Compare adjacent pairs, extract first differing element as directed constraint
2. Build adjacency list + in-degree map
3. Check for invalid input (prefix longer than successor)
4. Kahn's BFS topological sort
5. If result length < number of nodes => cycle => return invalid
'''
print(template_2)Bygg självförtroende med svåra problem
Svåra problem verkar omöjliga i början, men blir hanterbara med rätt tankemodell. De viktigaste insikterna är:
- Separera ansvarsområden: lös varje delproblem för sig innan ni kopplar ihop dem
- Känn till era byggstenar: BFS/DFS, topologisk sortering, Dijkstra, DP-tabeller – svåra problem kombinerar dessa på oväntade sätt
- Börja med exempel: gå igenom problemet manuellt med ett litet exempel för att upptäcka den underliggande strukturen
- Verifiera delproblemen: när ni har implementerat fas 1 (bygga grafen), skriv ut grafen och verifiera den manuellt innan ni går vidare till fas 2
# Hard problem confidence-building practice plan
practice_plan = [
('Week 1', 'BFS/DFS fundamentals', ['Number of Islands', 'Clone Graph', 'Word Ladder I']),
('Week 2', 'Topological sort', ['Course Schedule I & II', 'Alien Dictionary (easy)']),
('Week 3', 'All-paths problems', ['All Paths to Target', 'Word Ladder II (hard)']),
('Week 4', 'Hard combos', ['Minimum Window Substring', 'Serialize/Deserialize Tree']),
]
print('4-week hard problem practice plan:')
for week, theme, problems in practice_plan:
print(f'\n{week} — {theme}:')
for p in problems:
print(f' - {p}')
print('\nAfter each problem, write:')
print(' 1. The pattern it belongs to')
print(' 2. The 2-3 key sub-problems')
print(' 3. One insight you would not have had before solving it')Snabbtest
Testa era kunskaper om begreppen Data Structures & Algorithms — Coding Interview Prep från den här lektionen.
Sammanfattning av lektionen
I denna lektion har ni lärt er att Word Ladder II använder BFS för att bygga en parents-mappning över alla föregångare på kortaste vägar och sedan DFS med backtracking för att räkna upp alla kortaste vägar genom att följa föregångarna från slut till start, att Alien Dictionary extraherar riktade begränsningar från intilliggande ordpar och tillämpar Kahns topologiska sortering för att ordna tecken, och returnerar en tom sträng när en cykel upptäcks, samt att svåra problem kan delas upp i flera delproblem – att bygga grafen, hitta avstånd och återskapa vägar – där varje del löses självständigt med välbekanta algoritmer. Ni har nu slutfört hela DSA Interview Prep-kursen. Tillämpa alla mönster och tekniker från detta spår i era intervjuer med självförtroende.
Lär dig Python med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Genomgång av svåra problem: Word Ladder II och Alien Dictionary” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen DSA Interview Prep, inklusive ”Genomgång av svåra problem: Word Ladder II och Alien Dictionary”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i DSA Interview Prep innehåller totalt 4 lektioner.
Vad lär jag mig i ”Genomgång av svåra problem: Word Ladder II och Alien Dictionary”?
Ta er an två svåra problem från början till slut – word-ladder-II med BFS + backtracking och alien-dictionary med topologisk sortering – med en fullständig förklaring. Ni övar på DSA Interview Prep med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig DSA Interview Prep?
Du behöver inga förkunskaper. Utbildningen i DSA Interview Prep på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Genomgång av svåra problem: Word Ladder II och Alien Dictionary”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här DSA Interview Prep-lektionen?
Ja. Varje DSA Interview Prep-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Fuskblad för mönsterigenkänning
- Tidsbegränsad övningsintervju: enkla och medelsvåra problem
- Hantering av specialfall och kommunikation under intervjun
- Genomgång av svåra problem: Word Ladder II och Alien Dictionary