OK, Now To The More Efficient Solution:: O (N Log N)
OK, Now To The More Efficient Solution:: O (N Log N)
OK, I will describe first the simplest solution which is O(N^2), where N is the size of
the set. There also exists a O(N log N) solution, which I will describe also. Look here
for it at the section Efficient algorithms.
I will assume the indices of the array are from 0 to N-1. So let's define DP[i] to be the
length of the LIS(Longest increasing subsequence) which is ending at element with
index i. To compute DP[i] we look at all indices j < i and check both if DP[j] + 1 >
DP[i] and array[j] < array[i](we want it to be increasing). If this is true we can update
the current optimum for DP[i]. To find the global optimum for the array you can take
the maximum value from DP[0..N-1].
int maxLength = 1, bestEnd = 0;
DP[0] = 1;
prev[0] = -1;
for (int i = 1; i < N; i++)
{
DP[i] = 1;
prev[i] = -1;
for (int j = i - 1; j >= 0; j--)
if (DP[j] + 1 > DP[i] && array[j] < array[i])
{
DP[i] = DP[j] + 1;
prev[i] = j;
}
if (DP[i] > maxLength)
{
bestEnd = i;
maxLength = DP[i];
}
}
I use the array prev to be able later to find the actual sequence not only its length. Just
go back recursively from bestEnd in a loop using prev[bestEnd]. The -1 value is a sign
to stop.
OK, now to the more efficient O(N log N) solution:
Let S[pos] be defined as the smallest integer that ends an increasing sequence of
length pos.
Now iterate through every integer X of the input set and do the following:
1. If X > last element in S, then append X to the end of S. This essentialy means we
have found a new largest LIS.
2. Otherwise find the smallest element in S, which is >= than X, and change it to X.
Because S is sorted at any time, the element can be found using binary search in
log(N).
Total runtime - N integers and a binary search for each of them - N * log(N) = O(N log
N)
Now let's do a real example:
Set of integers: 2 6 3 4 1 2 9 5 8
Steps:
0.
1.
2.
3.
4.
5.
6.
7.
8.
9.
S
S
S
S
S
S
S
S
S
S
=
=
=
=
=
=
=
=
=
=
Now to the important thing - how do we update the parent array? There are two
options:
1. If X > last element in S, then parent[indexX] = indexLastElement. This
means the parent of the newest element is the last element. We just prepend X to
the end of S.
2. Otherwise find the index of the smallest element in S, which is >= than X, and