Oversigt over mønstergenkendelse
Knyt 15 almindelige problemsignaler (sorteret array, behov for alle kombinationer, maksimering af værdi under en begrænsning osv.) til de algoritmemønstre, der løser dem hurtigst.
Oversigt over mønstergenkendelse er en gratis Forberedelse til kodeinterviews-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Forberedelse til kodeinterviews, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Forberedelse til kodeinterviews-kurset indeholder 4 lektioner i alt.
Mønstergenkendelseslegen på 60 sekunder
I en rigtig jobsamtale har du cirka 60 sekunder efter at have læst et problem til at identificere, hvilket algoritmisk mønster der passer, før intervieweren forventer, at du begynder at kode. Det er den vigtigste færdighed at udvikle — ikke at lære implementeringer udenad, men at genkende, hvilket værktøj du skal tage i brug.
Mønstergenkendelse opstår ved at knytte problemsignaler (ord og begrænsninger i problemformuleringen) til kendte algoritmefamilier. Når du har identificeret mønstret, bliver implementeringen en øvelse i at udfylde en skabelon. Denne lektion er en systematisk huskeseddel over de 15 mest almindelige problemsignaler og de tilhørende mønstre.
# The recognition process
recognition_steps = [
'1. Read the problem once fully (do not start coding)',
'2. Identify the data structure: array, string, tree, graph, matrix?',
'3. Identify the ask: find min/max, count ways, enumerate, detect cycle...?',
'4. Note the constraint: n<=20 (bitmask), sorted (binary search), DAG (topo sort)?',
'5. Map signal -> pattern',
'6. State the pattern and complexity to the interviewer before coding',
'7. Handle edge cases mentally before writing',
]
for step in recognition_steps:
print(step)Signal 1-3: Mønstre for arrays og strenge
De hyppigste problemsignaler for arrays og strenge:
- Sorteret array + find målværdi → Binær søgning O(log n)
- Find par/triplet, der summerer til målværdien → To pointere O(n), hvis arrayet er sorteret, hash map O(n), hvis det ikke er sorteret
- Længste/korteste delarray/delstreng, der opfylder en betingelse → Sliding window O(n)
- Største/mindste sum i et sammenhængende delarray → Kadane's algorithm O(n)
- Registrering af dubletter → Hash set O(n) eller sortering O(n log n)
Hvis arrayet er sorteret, bør du altid først overveje binær søgning. Usorteret + målsum + O(n) = næsten altid et hash map til opslag af komplementet.
# Quick recognition: array/string signals
signals = [
('Sorted array, find element', 'Binary search O(log n)'),
('Find two elements summing to K', 'Sort+two-ptr O(n log n) or hash O(n)'),
('Longest subarray with property P', 'Sliding window (variable size) O(n)'),
('Max sum contiguous subarray', 'Kadane algorithm O(n)'),
('Anagram/permutation check', 'Frequency map (Counter) O(n)'),
('Contains duplicate', 'Hash set O(n)'),
('Merge two sorted arrays/lists', 'Two pointers O(n+m)'),
('Rotate / shift array', 'Reverse trick O(n) in-place'),
('Next permutation', 'Find rightmost ascent + swap + reverse'),
('Maximum product subarray', 'Track max and min (handles negatives)'),
]
for signal, pattern in signals:
print(f'{signal:45s} => {pattern}')Signal 4-6: Mønstre for træer og grafer
Træ- og grafrelaterede problemsignaler og deres mønstre:
- Gennemløb niveau for niveau / korteste sti i en uvægtet graf → BFS med deque O(V+E)
- Udforsk alle stier / registrering af cyklusser / DFS-rækkefølge → Rekursiv eller iterativ DFS O(V+E)
- BST + in-order-egenskaber (element nr. k, sorteret rækkefølge) → In-order DFS O(n)
- Laveste fælles forfader → Rekursiv ned gennem træet med sporing af sti O(n)
- Sammenhængende komponenter / foren to grupper → DSU O(n × alpha(n))
# Tree/graph signal recognition
tree_graph_signals = [
('Level-order / minimum depth / word ladder', 'BFS with deque'),
('All paths / path sum / all permutations tree', 'DFS recursive'),
('Cycle detection (undirected)', 'DFS with parent / DSU'),
('Cycle detection (directed) / course schedule', 'DFS three-color / Kahn topo sort'),
('Shortest path weighted graph', 'Dijkstra (non-neg) / Bellman-Ford (neg)'),
('All-pairs shortest path', 'Floyd-Warshall O(V^3)'),
('Topological order', 'Kahn BFS topo sort'),
('Min spanning tree', 'Kruskal (DSU) / Prim (heap)'),
('Dynamic connectivity / union-find', 'DSU path compression + union by rank'),
('Autocomplete / prefix search', 'Trie'),
('BST kth smallest / range sum', 'In-order DFS'),
]
for signal, pattern in tree_graph_signals:
print(f'{signal:50s} => {pattern}')Signal 7-9: Signaler for dynamisk programmering
DP-signaler er de sværeste at genkende. Se efter disse nøgleord:
- 'Antal måder at...' → Optællings-DP (læg delproblemernes antal sammen)
- 'Minimums-/maksimumsomkostning for at opnå...' → Optimerings-DP (tag minimum eller maksimum af delproblemerne)
- 'Kan vi opnå...' (mulighed) → Boolsk DP (OR af delproblemer)
- Delproblem defineret af to strengindekser → 2D DP (LCS, redigeringsafstand)
- Tag eller spring elementer over under en kapacitetsbegrænsning → Rygsæk-DP
- Optimal delstruktur + overlappende delproblemer → Undersøg rekursionstræet for gentagne kald → DP
# DP signal recognition
dp_signals = [
('Number of ways to climb stairs / decode string', '1D DP (Fibonacci-like)'),
('Minimum cost to reach end / coin change', '1D DP (greedy fails)'),
('Longest increasing subsequence', '1D DP O(n^2) or patience sort O(n log n)'),
('Longest common subsequence of two strings', '2D DP O(mn)'),
('Edit distance between two strings', '2D DP O(mn) (LCS variant)'),
('Partition array into two equal subsets', '0/1 knapsack boolean DP'),
('Fill knapsack with max value under weight limit', '0/1 knapsack optimisation DP'),
('Burst balloons / matrix chain multiplication', 'Interval DP'),
('Palindrome partitioning minimum cuts', 'Interval DP + prefix palindrome'),
('Rob houses in circle', '1D DP × 2 (linear sub-problems)'),
]
for signal, pattern in dp_signals:
print(f'{signal:55s} => {pattern}')Signal 10-12: Signaler for heap, stack og greedy
Signaler for heap-, monotone stack- og greedy-problemer:
- Top-K-elementer / det k.-største eller k.-mindste → Heap (min-heap for de K største, max-heap for det k.-mindste) O(n log k)
- Median i en datastrøm → To heaps (max-heap for den lille halvdel + min-heap for den store halvdel)
- Næste større/mindre element → Monoton stack O(n)
- Rektangel med størst areal / opsamling af vand → Monoton stack O(n)
- Intervalplanlægning / maksimering af ikke-overlappende intervaller → Greedy (sortér efter sluttidspunkt)
# Heap / stack / greedy signals
heap_stack_greedy = [
('Top-K frequent elements', 'Min-heap size K: O(n log k)'),
('Kth largest in array', 'Max-heap pop K times: O(n + k log n)'),
('Streaming median', 'Two heaps (max + min): O(log n) per insert'),
('Merge K sorted lists', 'Min-heap of (val, list_idx): O(n log k)'),
('Next greater element', 'Monotonic decreasing stack: O(n)'),
('Largest rectangle in histogram', 'Monotonic increasing stack: O(n)'),
('Sliding window maximum', 'Monotonic decreasing deque: O(n)'),
('Trapping rain water', 'Two pointers OR monotonic stack: O(n)'),
('Jump game reachability / minimum jumps', 'Greedy range expansion: O(n)'),
('Merge overlapping intervals', 'Sort by start, linear scan: O(n log n)'),
('Gas station circular', 'Greedy: start from reset point: O(n)'),
('Task scheduler with cooldown', 'Greedy: sort by frequency: O(n log n)'),
]
for signal, pattern in heap_stack_greedy:
print(f'{signal:45s} => {pattern}')Signal 13-15: Backtracking og bitmanipulation
Signaler for backtracking og bitmanipulation:
- Generér alle delmængder / permutationer / kombinationer → Backtracking O(2^n eller n!)
- Opfyldelse af begrænsninger (N-queens, Sudoku) → Backtracking med beskæring
- Find ét manglende / unikt element → XOR O(n) O(1)-plads
- Enumerér alle delmængder af et lille sæt (n ≤ 20) → 2^n-enumerering med bitmaske
- Optælling af satte bits / kontrol af potens af to → Bittricks (n & (n-1))
- DP med tilstandskomprimering for et lille sæt → Bitmaske-DP O(2^n × n)
# Backtracking and bit signals
bt_bit_signals = [
('Generate all subsets of array', 'Backtracking O(n * 2^n) / bitmask'),
('Generate all permutations', 'Backtracking O(n * n!)'),
('Combination sum with target', 'Backtracking with pruning'),
('Word search in grid', 'Backtracking DFS on grid O(m*n*4^L)'),
('N-queens placement', 'Backtracking with column/diag sets'),
('Find single unique element (all others x2)', 'XOR all: O(n) O(1)'),
('Missing number in 0..n', 'XOR or sum formula: O(n) O(1)'),
('Count set bits in n', 'n &= n-1 loop or DP O(n)'),
('Check power of two', 'n > 0 and n & (n-1) == 0'),
('Travelling salesman (n<=20)', 'Bitmask DP O(2^n * n^2)'),
('Number with max XOR in array', 'Trie on binary representation'),
]
for signal, pattern in bt_bit_signals:
print(f'{signal:50s} => {pattern}')Begrænsningsanalyse: Hvad N fortæller dig
Begrænsningen for inddataens størrelse n fortæller dig direkte, hvilken tidskompleksitet der er acceptabel — og dermed hvilken algoritmefamilie:
- n ≤ 20: O(2^n) eller O(n!) er acceptabelt — bitmaske-DP, backtracking
- n ≤ 500: O(n³) er acceptabelt — Floyd-Warshall, DP med udtømmende søgning
- n ≤ 5000: O(n²) er acceptabelt — naiv DP, kvadratisk sortering
- n ≤ 10^6: O(n log n) kræves — merge sort, heap, binær søgning
- n ≤ 10^8: O(n) kræves — to pointere, sliding window, lineær DP
Denne begrænsningsanalyse bør være dit første trin, efter du har læst problemet — før du vælger en algoritme.
# Constraint -> acceptable complexity -> algorithm family
complexity_map = [
('n <= 20', 'O(2^n) or O(n!)', 'Bitmask DP, backtracking/permutations'),
('n <= 500', 'O(n^3)', 'Floyd-Warshall, cubic DP, brute force'),
('n <= 5000', 'O(n^2)', 'Quadratic DP, bubble/insertion sort'),
('n <= 100000', 'O(n log n)', 'Merge sort, heap, binary search, topo sort'),
('n <= 1000000', 'O(n)', 'Linear DP, two pointers, sliding window, hash'),
('n <= 10^8', 'O(n) tight', 'Only simplest O(n) — no large constants'),
('n <= 10^18', 'O(log n) or O(1)', 'Math / number theory, binary search on answer'),
]
print(f'{'Constraint':15s} {'Complexity':15s} {'Algorithm Family'}')
print('-'*70)
for constraint, complexity, algorithms in complexity_map:
print(f'{constraint:15s} {complexity:15s} {algorithms}')Problem → Mønster: Lynøvelse
Øv denne sammenkobling, indtil den sker automatisk. Læs hver problembeskrivelse, og identificér mønstret før du ser på løsningen. Hastighed er vigtig — under et interview bør du identificere mønstret på under 60 sekunder:
- 'Givet et sorteret array, find ud af, om to elementer summerer til K'
- 'Givet et træ, find diameteren (den længste sti mellem to vilkårlige noder)'
- 'Givet n opgaver med nedkølingstid k, find det mindste antal CPU-intervaller'
- 'Givet en streng, find den længste palindromiske delstreng'
- 'Givet 1..n med ét manglende element, find det manglende tal'
# Quick-fire pattern recognition answers
problems = [
('Sorted array: two elements sum to K',
'Two pointers (left from start, right from end): O(n)'),
('Tree diameter (longest path)',
'DFS returning (height, max_diameter) pair: O(n)'),
('Task scheduler with cooldown k',
'Greedy: (max_freq - 1)*(k+1) + count_of_max_freq: O(n log n)'),
('Longest palindromic substring',
'Expand around centre OR Manacher: O(n^2) or O(n)'),
('Missing number in 1..n',
'XOR all indices and values: O(n) O(1)'),
('Number of islands in binary grid',
'BFS/DFS flood fill counting connected components: O(m*n)'),
('Decode string like 3[a2[bc]] -> aaabcbcaabcbc',
'Stack to handle nested brackets: O(n)'),
('Valid parentheses [(){[]}]',
'Stack push open, pop+match on close: O(n)'),
]
for problem, solution in problems:
print(f'Q: {problem}\nA: {solution}\n')Advarselstegn: Når dit mønster fejler
Selv erfarne udviklere vælger først det forkerte mønster. Genkend disse signaler på, at din nuværende tilgang er forkert, og skift spor:
- Din O(n²)-løsning består små test, men giver TLE på store input → du har brug for et hash map, binær søgning eller en monoton struktur
- Din greedy-tilgang fejler på et modeksempel → prøv DP
- Dit DP-tilstandsrum er for stort → se efter et bevis for en greedy-tilgang eller en smartere tilstandsdefinition
- Din BFS giver et forkert svar → undersøg, om du har brug for Dijkstra (vægtet) i stedet for BFS (uvægtet)
- Du får null pointer-undtagelser → tilføj basistilfælde og beskyttelse mod kanttilfælde, før du implementerer
# Red flags and recovery strategies
red_flags = [
('TLE on large n', 'Check complexity; switch from O(n^2) to O(n log n) or O(n)'),
('WA with greedy', 'Find a counter-example; switch to DP or prove exchange arg'),
('DP table huge', 'State compression (bitmask/rolling array) or different state'),
('BFS gives wrong shortest path', 'Check if edges have weights; use Dijkstra instead'),
('Stack overflow in recursion', 'Add memoisation or convert to iterative with explicit stack'),
('Off-by-one in binary search', 'Use half-open intervals [lo, hi); verify with 2-element test'),
('DSU wrong answer', 'Check 0-indexed vs 1-indexed; check union direction'),
('Backtracking TLE', 'Add pruning conditions; ensure undo step is correct'),
]
print('Pattern | Recovery')
print('-'*70)
for flag, recovery in red_flags:
print(f'{flag:40s} => {recovery}')Sådan kommunikerer du mønstergenkendelse under interviews
Under interviews viser du ekspertise ved at sætte ord på din mønstergenkendelse og giver intervieweren mulighed for at guide dig, hvis du er på afveje. Brug denne struktur til dit manuskript:
- 'Jeg bemærker, at arrayet er sorteret, så jeg overvejer binær søgning...'
- 'Problemet beder om det maksimale delarray, hvilket er et klassisk problem for Kadane's algorithm...'
- 'Vi har brug for alle mulige delmængder, hvilket tyder på backtracking med et rekursionstræ...'
- 'Begrænsningen n ≤ 20 fortæller mig, at 2^n = 1M er acceptabelt, så bitmaske-DP kunne fungere...'
Når du har angivet mønstret, skal du nævne tids- og plads-kompleksiteten, før du skriver en eneste kodelinje. Det viser, at du tænker på effektivitet før implementeringen.
# Interview communication template
def communicate_approach(problem, pattern, time_complexity, space_complexity, edge_cases):
print(f'Problem: {problem}')
print(f'Pattern: {pattern}')
print(f'Time: {time_complexity}, Space: {space_complexity}')
print(f'Edge cases to handle: {", ".join(edge_cases)}')
print()
# Example communications
communicate_approach(
problem='Find longest substring without repeating characters',
pattern='Sliding window with a set tracking current window characters',
time_complexity='O(n)',
space_complexity='O(min(n, alphabet_size))',
edge_cases=['empty string', 'all same characters', 'all unique characters']
)
communicate_approach(
problem='Given sorted matrix, find if target exists',
pattern='Binary search or staircase search (top-right corner): eliminate row or column each step',
time_complexity='O(m + n)',
space_complexity='O(1)',
edge_cases=['empty matrix', 'single element', 'target at corners']
)Opbygning af dit ordforråd til mønstergenkendelse
Den hurtigste måde at opbygge mønstergenkendelse på er at løse problemer i tematiske grupper — ikke tilfældigt. Brug en uge på kun sliding window-problemer. Derefter problemer med to pointere. Så DP-problemer. Når du løser 20 problemer af samme type, opbygger du hurtigt intuitionen til at genkende det mønster ved første øjekast.
Efter hvert problem skal du skrive en 'mønsternote' på én linje: problemsignalet og det mønster, det udløste. Lav din egen huskeseddel. Når du har løst 200 problemer i tematiske grupper, vil du kunne genkende cirka 90 % af interviewproblemer på under 30 sekunder — de resterende 10 % kræver omhyggelig analyse selv for erfarne udviklere.
# Personal pattern note template
pattern_notes = [
{'signal': 'sorted array + two sum', 'pattern': 'two pointers', 'example': 'LC 167 Two Sum II'},
{'signal': 'longest X without repeating', 'pattern': 'sliding window + set', 'example': 'LC 3 Longest Substring'},
{'signal': 'max sum subarray', 'pattern': 'Kadane', 'example': 'LC 53 Max Subarray'},
{'signal': 'permutations/subsets', 'pattern': 'backtracking', 'example': 'LC 46 Permutations'},
{'signal': 'tree path sum', 'pattern': 'DFS with accumulator', 'example': 'LC 112 Path Sum'},
{'signal': 'course schedule', 'pattern': 'Kahn topo sort', 'example': 'LC 207 Course Schedule'},
{'signal': 'top-K elements', 'pattern': 'min-heap size K', 'example': 'LC 215 Kth Largest'},
]
print(f'{'Signal':40s} {'Pattern':30s} {'Example'}')
print('-'*90)
for note in pattern_notes:
print(f'{note["signal"]:40s} {note["pattern"]:30s} {note["example"]}')Hurtigt tjek
Test din forståelse af begreberne fra lektionen i Data Structures & Algorithms — Coding Interview Prep.
Opsummering af lektionen
I denne lektion lærte du: mønstergenkendelse knytter problemsignaler til algoritmefamilier — et sorteret array antyder binær søgning, 'alle delmængder' antyder backtracking, og 'minimumsomkostning' antyder DP, begrænsningen n fortæller dig, hvilken kompleksitet der er acceptabel: n ≤ 20 tillader O(2^n), mens n ≤ 10^6 kræver O(n log n) eller bedre, og at sætte ord på mønstret og kompleksiteten før kodning viser ekspertise og giver intervieweren mulighed for at give feedback. Næste gang omsætter vi mønstergenkendelse til praksis med tidsbegrænsede prøveinterviewproblemer på let og mellemsvær sværhedsgrad.
Lær Forberedelse til kodeinterviews med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 90
- Lektioner
- 360
Ofte stillede spørgsmål
Er lektionen “Oversigt over mønstergenkendelse” gratis?
Ja — hele teksten til “Oversigt over mønstergenkendelse” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Forberedelse til kodeinterviews-kurset, skal du opgradere til CoddyKit PRO. Forberedelse til kodeinterviews-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Oversigt over mønstergenkendelse”?
Knyt 15 almindelige problemsignaler (sorteret array, behov for alle kombinationer, maksimering af værdi under en begrænsning osv.) til de algoritmemønstre, der løser dem hurtigst. Du øver dig i Forberedelse til kodeinterviews med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Forberedelse til kodeinterviews?
Der kræves ingen tidligere erfaring. Forberedelse til kodeinterviews på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Oversigt over mønstergenkendelse”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Forberedelse til kodeinterviews-lektion?
Ja. Alle Forberedelse til kodeinterviews-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Oversigt over mønstergenkendelse
- Tidsbegrænset prøveinterview: Nemme og mellemsvære problemer
- Håndtering af kanttilfælde og kommunikation som interviewperson
- Gennemgang af svære problemer: Word Ladder II og Alien Dictionary