awesome-everything EN
↑ Обратно к восхождению

Алгоритмы с нуля

Инструментарий: распознавание паттернов в коде

Суть Прочти четыре наброска кода, распознай, какую технику каждый реализует (или должен), и выбери верную структуру данных или самую рычажную правку.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 14 min

На собеседовании или код-ревью тебе редко дают помеченную задачу — тебе дают фрагмент и ограничение. Навык в том, чтобы прочесть цикл и назвать технику, которую он реализует, или заметить, что выбранная структура неверна. Прочти каждый набросок, затем ответь.

Цель

Потренируй распознавательную половину инструментария: по коду определи паттерн, оцени, подходит ли структура данных доминирующей операции, и выбери изменение, которое реально сдвигает сложность.

Фрагмент 1 — вложенный цикл по отсортированным данным

def has_pair_with_sum(a, target):   # a is sorted ascending
    n = len(a)
    for i in range(n):
        for j in range(i + 1, n):
            if a[i] + a[j] == target:
                return True
    return False
Викторина

Вход отсортирован, но это O(n^2). К какому паттерну зовёт отсортированный вход и какова итоговая сложность?

Фрагмент 2 — рекурсия, которая пересчитывает

def ways(n, coins):
    if n == 0: return 1
    if n < 0 or not coins: return 0
    # use coins[0] again, or drop it
    return ways(n - coins[0], coins) + ways(n, coins[1:])
Викторина

Это корректно, но экспоненциально при большом n. Каков точный диагноз и стандартная правка?

Фрагмент 3 — текущий k-й элемент

import heapq

def stream_kth_largest(stream, k):
    h = []                       # what kind of heap?
    for x in stream:
        heapq.heappush(h, x)     # Python heapq is a MIN-heap
        if len(h) > k:
            heapq.heappop(h)     # pops the smallest
    return h[0]                  # the k-th largest seen so far
Викторина

Этот код держит текущий k-й наибольший через min-heap размера k. Почему именно MIN-heap (а не max-heap) — верная структура здесь?

Фрагмент 4 — неограниченное окно

def longest_unique_substring(s):
    seen = set()
    best = 0
    for r in range(len(s)):
        while s[r] in seen:
            seen.add(s[r])       # BUG: should shrink from the left
        seen.add(s[r])
        best = max(best, len(seen))
    return best
Викторина

Задумана техника скользящего окна по строке. Окно никогда не сжимается, поэтому цикл сломан. Каков верный механизм?

Итог

Чтение кода ради паттерна — тот же поток, прогнанный в обратную сторону: вложенный цикл по отсортированным данным должен быть two pointers (O(n)); рекурсия, пересчитывающая одинаковые состояния, кричит о мемоизации или табуляции (DP); текущий k-й элемент задаёт конкретную ориентацию кучи тем, какой элемент нужно дёшево вытеснять; а ‘длиннейший непрерывный диапазон при условии’ — это скользящее окно, чей левый указатель движется только вперёд. Назови паттерн, сверь структуру данных с доминирующей операцией, затем измени то единственное, что сдвигает сложность.

Продолжить восхождение ↑Инструментарий: капстоун-вызов решения задач
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.