Более простая задача - найти длину самой длинной увеличивающейся подпоследовательности. Вы можете сосредоточиться на понимании этой проблемы в первую очередь. Единственное отличие в алгоритме состоит в том, что он не использует массив P .
x является вводом последовательности, поэтому его можно инициализировать как:
x = [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]
m отслеживает лучшую подпоследовательность каждой длины , найденную до сих пор. Наилучшим является тот, который имеет наименьшее конечное значение (после него можно добавить более широкий диапазон значений). Длина и конечное значение являются единственными данными, которые необходимо сохранить для каждой подпоследовательности.
Каждый элемент m представляет подпоследовательность. Для м [Дж] ,
- j - длина подпоследовательности.
- m [j] - индекс (в x ) последнего элемента подпоследовательности.
- , x [m [j]] - значение последнего элемента подпоследовательности.
L - длина самой длинной найденной подпоследовательности. Первые L значения m действительны, остальные не инициализированы. m может начинаться с того, что первый элемент равен 0, остальные неинициализированы. L увеличивается при запуске алгоритма, равно как и число инициализированных значений m .
Вот пример запуска. x [i] и m в конце каждой итерации (но вместо индексов используются значения последовательности).
Поиск в каждой итерации ищет место для размещения x [i] . Оно должно быть как можно дальше вправо (чтобы получить самую длинную последовательность) и быть больше значения слева от него (так что это возрастающая последовательность).
0: m = [0, 0] - ([0] is a subsequence of length 1.)
8: m = [0, 0, 8] - (8 can be added after [0] to get a sequence of length 2.)
4: m = [0, 0, 4] - (4 is better than 8. This can be added after [0] instead.)
12: m = [0, 0, 4, 12] - (12 can be added after [...4])
2: m = [0, 0, 2, 12] - (2 can be added after [0] instead of 4.)
10: m = [0, 0, 2, 10]
6: m = [0, 0, 2, 6]
14: m = [0, 0, 2, 6, 14]
1: m = [0, 0, 1, 6, 14]
9: m = [0, 0, 1, 6, 9]
5: m = [0, 0, 1, 5, 9]
13: m = [0, 0, 1, 5, 9, 13]
3: m = [0, 0, 1, 3, 9, 13]
11: m = [0, 0, 1, 3, 9, 11]
7: m = [0, 0, 1, 3, 7, 11]
15: m = [0, 0, 1, 3, 7, 11, 15]
Теперь мы знаем, что есть подпоследовательность длины 6, заканчивающаяся 15. Фактические значения в подпоследовательности можно найти, сохранив их в массиве P во время цикла.
Получение лучшей подпоследовательности:
P сохраняет предыдущий элемент в самой длинной подпоследовательности (в виде индекса x) для каждого числа и обновляется по мере продвижения алгоритма. Например, когда мы обрабатываем 8, мы знаем, что оно идет после 0, поэтому сохраните факт, что 8 после 0, в P . Вы можете работать в обратном направлении от последнего номера, как связанный список, чтобы получить всю последовательность.
Так что для каждого номера мы знаем число, которое предшествовало ему. Чтобы найти подпоследовательность, заканчивающуюся на 7, мы смотрим на P и видим, что:
7 is after 3
3 is after 1
1 is after 0
Итак, у нас есть подпоследовательность [0, 1, 3, 7].
Подпоследовательности, заканчивающиеся на 7 или 15, разделяют несколько чисел:
15 is after 11
11 is after 9
9 is after 6
6 is after 2
2 is after 0
Итак, у нас есть подпоследовательности [0, 2, 6, 9, 11] и [0, 2, 6, 9, 11, 15] (самая длинная возрастающая подпоследовательность)