The longest increasing subsequence problem can also be related to finding the [[longest path problem|longest path]] in a [[directed acyclic graph]] derived from the input sequence: we construct a vertex per sequence value and connect values ''x'' and ''y'' by an edge when ''x'' is both smaller than ''y'' and occurs earlier than it in the sequence. Longest paths in DAGs can be found in time linear in the size of the DAG, but in this case the size can be quadratic in the sequence length, so this algorithm is not asymptotically faster than the dynamic programming one.
== Efficient algorithms ==
We describe an efficient algorithm for the problem that needs no data structures, only arrays and binary searching.
The algorithm processes the sequence elements in order, maintaining the longest increasing subsequence found so far. Denote the sequence values as X[0], X[1], etc. Then, after processing X[''i''], the algorithm will have stored values in two arrays, described below:
:M[''j''] — stores the position ''k'' of the smallest value X[''k''] such that ''k'' ≤ ''i'' and there is an increasing subsequence of length ''j'' ending at X[''k'']
:P[''k''] — stores the position of the predecessor of X[''k''] in the longest increasing subsequence ending at X[''k'']
In addition the algorithm stores a variable L representing the length of the longest increasing subsequence found so far.
Note that, at any point in the algorithm, the sequence
:X[M[1]], X[M[2]], ..., X[M[L]]
is nondecreasing. For, if there is an increasing subsequence of length ''i'' ending at X[M[''i'']], then there is also a subsequence of length ''i''-1 ending at a smaller value: namely the one ending at P[M[''i'']]. Thus, we may do binary searches in this sequence in logarithmic time.
The algorithm, then, proceeds as follows.
L = 0
for ''i'' = 0, 1, ... n:
binary search for the largest ''j'' ≤ L such that X[M[''j'']] < X[''i''] (or set ''j'' = 0 if no such value exists)
P[''i''] = M[''j'']
if ''j'' == L or X[''i''] < X[M[j+1]]:
M[''j''+1] = ''i''
L = max(L, ''j''+1)
The result of this is the length of the longest sequence in L. The actual longest sequence can be found by backtracking through the P array:
:..., X[P[P[M[L]]]], X[P[M[L]]], X[M[L]]
== See also ==
|