Все темы
115

Самая длинная цепочка, которую можно сохранить по порядку

Tier 1Закрыто

Где применяется

1. Задача

Ты сравниваешь две версии файла и хочешь, чтобы diff показал, что осталось прежним. Строки добавляли, удаляли, переставляли. Неизменная часть это самый длинный набор строк, которые есть в обоих файлах в одном и том же порядке, даже если между ними вставлены другие строки. Именно это git diff считает каждый день.

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

У обоих вопросов одна форма: выбери самое длинное, что можно сохранить по порядку. Элементы между выбранными разрешено пропускать.

Этот шаг из платной части

Бесплатные шаги в начале курса (их 33) открыты всем: урок, задача и тесты. Этот шаг открывается с полным доступом. Начни с бесплатного аккаунта и бесплатных шагов.

Завести бесплатный аккаунтПосмотреть, что входит
Самая длинная возрастающая подпоследовательность
longestIncreasingSubsequence([2, 5, 3, 7, 4, 8])
arr
2
5
3
7
4
8
dp[i]: самая длинная возрастающая цепочка, которая кончается на arr[i]
1
1
1
1
1
1
best = 1

Ищем самую длинную возрастающую подпоследовательность. Каждый dp[i] начинается с 1: само arr[i] уже цепочка длины 1.

Гонка скорости
Самая длинная возрастающая подпоследовательность одних и тех же 11 чисел: перебор подмножеств, квадратичная таблица или терпеливая сортировка

Столбики: исходные числа, их никто не переставляет. Подсвечено число, которое сейчас читается; при выборе подмножества подсвечены все его элементы.

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

Перебор всех подмножеств O(2ⁿ·n)
операций: 0
Квадратичная таблица O(n²)
операций: 0
Терпеливая сортировка с бинарным поиском O(n log n)
операций: 0

 

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

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

n = 10
Перебор всех подмножеств3,6 тыс. · меньше 1 мс
Квадратичная таблица55 · меньше 1 мс
Терпеливая сортировка с бинарным поиском26,6 · меньше 1 мс
n = 20
Перебор всех подмножеств3,7 млн · 37 мс
Квадратичная таблица210 · меньше 1 мс
Терпеливая сортировка с бинарным поиском63,2 · меньше 1 мс
n = 40
Перебор всех подмножеств3,8 трлн · 11 ч
Квадратичная таблица820 · меньше 1 мс
Терпеливая сортировка с бинарным поиском146,4 · меньше 1 мс

Как узнать

DP над подпоследовательностями (LIS / LCS / расстояние редактирования) (DP on subsequences (LIS / LCS / edit distance))

Эти слова в условии значат этот паттерн

  • самая длинная возрастающая подпоследовательность
  • самая длинная общая подпоследовательность двух строк
  • минимум правок, чтобы превратить одну строку в другую
  • сохранить относительный порядок, можно пропускать элементы
  • diff или выравнивание двух последовательностей

Похоже, но не то

  • Динамическое программирование (1-D) (Dynamic programming (1-D))

    Там хватает одного индекса. Сравнению двух последовательностей нужны два.

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

    Та страница режет одну строку на куски. Эта выравнивает две последовательности.

  • Бинарный поиск (массив) (Binary search (array))

    Версия возрастающей подпоследовательности за n log n использует бинарный поиск. Табличная версия медленнее.

  • Два указателя (в одну сторону) (Two pointers (same direction))

    Проверке, является ли строка подпоследовательностью, таблица не нужна. Поиску наибольшей общей нужна.

Одна последовательность из n элементов стоит O(n²) времени. Две длины n и m стоят O(nm), и хватает одной строки памяти.

На LeetCode

Задачи, где элементы выбирают по порядку с пропусками так, чтобы каждый следующий рос, делился или сцеплялся с предыдущим. Для каждой позиции храни лучший ответ, который на ней кончается, проверяя все позиции раньше, это O(n^2).

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