Бесплатная бета: 60 дней полного доступа, без карты.мест осталось: 84Зарегистрироваться бесплатно

Мы используем необходимые куки для работы сайта (вход и язык). Если ты согласишься, мы также загрузим Google Analytics, чтобы видеть, какие страницы читают, и Google reCAPTCHA для защиты форм обратной связи и сообщений об ошибке от спама. Политика конфиденциальности

Все паттерны

DP на строках (word break)

DP on strings (word break)

O(n2)

Режьте строку в каждой позиции и спрашивайте, годится ли получившийся кусок. Таблица достижимых позиций убирает повторы.

Обновлено 17 окт. 2026 г.

DP на строках (word break): как это работает?

Состояние i значит, что первые i символов можно разрезать. Нулевое состояние истинно по определению.

Для каждой позиции i смотрите назад на все более ранние позиции j. Кусок между ними это кандидат в слово.

Разрез работает, если состояние j истинно и кусок это слово. Тогда истинно и состояние i.

Одного подходящего j достаточно. Прерывайте внутренний цикл сразу после находки.

Ответ лежит в последнем состоянии. Дальше позиции n ничего нет.

Каждая позиция решается ровно один раз. Именно это превращает экспоненту в таблицу.

Источники: Википедия: Динамическое программирование

  1. dp[0] = истинаРежем leetcode словами leet и code.
  2. dp[1] по dp[3] = ложьКуски l, le и lee словами не являются.
  3. dp[4] = истинаleet это слово, а dp[0] истинно.
  4. dp[5] по dp[7] = ложьНи одно слово не кончается в этих позициях.
  5. dp[8] = истинаcode идёт после dp[4]. Вся строка режется.
Разрезать строку на слова из словаря
wordBreak("catsdog", ["cat", "cats", "dog"])
s
c
a
t
s
d
o
g
ok[i]: T, если первые i букв режутся на слова
T
F
F
F
F
F
F
F
wordDict
catcatsdog
piece = -

Можно ли разрезать "catsdog" на слова из словаря? ok[0] истинно: пустому префиксу слова не нужны.

Гонка скорости
Разбиение строки "aaaaaaaaaaaab" на слова a, aa, aaa: простая рекурсия и таблица по префиксам

Столбики: сколько проверок по словарю начиналось с каждой позиции строки.

Одна операция: одна проверка по словарю. За каждый кадр все дорожки делают одинаковое число операций, поэтому медленная отстаёт.

Простая рекурсия O(2ⁿ)
операций: 0
Таблица по префиксам O(n²)
операций: 0

 

А если чисел больше

Операции для n чисел и примерное время при 100 миллионах простых операций в секунду. Это оценка по тому же счёту, а не замер.

n = 20
Простая рекурсия317 тыс. · 3,2 мс
Таблица по префиксам175 · меньше 1 мс
n = 40
Простая рекурсия62,2 млрд · 10 мин
Таблица по префиксам745 · меньше 1 мс
n = 60
Простая рекурсия12 220,2 трлн · 3,9 лет
Таблица по префиксам1,7 тыс. · меньше 1 мс

DP на строках (word break): шаблон кода

function wordBreak(s, wordDict) {
    const words = new Set(wordDict);
    const ok = new Array(s.length + 1).fill(false);
    ok[0] = true;
    for (let i = 1; i <= s.length; i++) {
        for (let j = 0; j < i; j++) {
            if (ok[j] && words.has(s.slice(j, i))) {
                ok[i] = true;
                break;
            }
        }
    }
    return ok[s.length];
}

DP на строках (word break): разбор примера

Наименьшее число разрезов на палиндромы

Разрежьте строку на куски, каждый из которых палиндром. Верните наименьшее число разрезов.

Один символ уже считается палиндромом.

Сначала отметьте все пары позиций, между которыми стоит палиндром.

Потом состояние i это наименьшее число разрезов для первых i символов. Палиндромный хвост стоит одного разреза.

function minCut(s) {
    const n = s.length;
    const isPal = Array.from({ length: n }, () => new Array(n).fill(false));

    for (let end = 0; end < n; end++) {
        for (let start = end; start >= 0; start--) {
            // the inside is already decided, because end - start only shrinks
            if (s[start] === s[end] && (end - start < 2 || isPal[start + 1][end - 1])) {
                isPal[start][end] = true;
            }
        }
    }

    const cuts = new Array(n + 1).fill(0);
    for (let i = 0; i <= n; i++) cuts[i] = i - 1; // cuts[0] is -1, so a whole palindrome costs 0

    for (let end = 0; end < n; end++) {
        for (let start = 0; start <= end; start++) {
            if (isPal[start][end]) {
                cuts[end + 1] = Math.min(cuts[end + 1], cuts[start] + 1);
            }
        }
    }

    return cuts[n];
}

DP на строках (word break): когда применять?

Паттерн «DP на строках (word break)» нужен, когда в условии есть слова «можно ли разбить строку на слова из словаря», «сегментировать строку по списку слов» или «булево значение достижимости в каждой точке разреза». Решение на нём обычно укладывается в O(n^2).

  • можно ли разбить строку на слова из словаря
  • сегментировать строку по списку слов
  • булево значение достижимости в каждой точке разреза
  • слитный текст нужно разделить на границы слов

Слова в условии для всех паттернов собраны в одной таблице: шпаргалка по паттернам алгоритмов.

DP на строках (word break): с чем путают?

Паттерн «DP на строках (word break)» чаще всего путают с этими паттернами: DP над подпоследовательностями (LIS / LCS / расстояние редактирования), Trie (префиксное дерево), Бэктрекинг и Хеш-множество / словарь.

DP на строках (word break): частые ошибки

  • Пересобирают подстроку на каждом шаге

    Вырезание внутри цикла каждый раз копирует символы. Сравнивайте позиции или идите по trie.

  • Идут по палиндромам не в ту сторону

    Внутренность обязана решаться раньше внешней. Растите по длине или ведите начало назад.

  • Забывают пустой префикс

    Нулевое состояние и позволяет первому слову начать разрез. Без него истины не будет никогда.

  • Перечисляют все разрезы, когда хватит одного

    Задача спрашивает только да или нет. Перечисление разрезов экспоненциально.

Паттерн «DP на строках (word break)» решает такие задачи с собеседований: Разбиение строки на слова, Разбиение строки на слова II, Разбиение на палиндромы II, Наибольшая палиндромная подстрока, Составные слова, Лишние символы в строке и Число способов расшифровки.

  • Разбиение строки на слова: Можно ли вообще разрезать строку.
  • Разбиение строки на слова II: Нужны все верные разрезы, поэтому возвращается бэктрекинг.
  • Разбиение на палиндромы II: Нужно число разрезов, а не сами части.
  • Наибольшая палиндромная подстрока: Та же таблица палиндромов, прочитанная иначе.
  • Составные слова: Каждое слово режется при помощи всех остальных.
  • Лишние символы в строке: Считается стоимость оставшихся букв.
  • Число способов расшифровки: Одна цифра или две, по фиксированному алфавиту.

DP на строках (word break): сложность по времени и памяти

У паттерна «DP на строках (word break)» целевая сложность O(n2).

n символов при словах до m дают O(nm). Множество или trie держат поиск около O(1).

Где этот паттерн стоит в 150 шагах