The idea to solve this problem goes as follows: Suppose there is an array of n element A. If the maximal length of the increasing sequence lying within the first k elements is known, denoted as L(k), then what we will do next is to compare A[k+1] with the maximal element of that increasing sequence, denoted as M[L(k)]. If A[k+1] is greater than M[L(k)], then the maximal length of the first (k+1) elements is L(k)+1, and M[L(k+1)] is assigned by A[k+1]; If A[k+1] is smaller than M[L(k)], then all the information about the increasing sequence with length L(k) will not be changed, however, A[k+1] may influence the increasing sequence with length L(k)-1, if A[k+1] is greater than its maximal element. If so, M[L(k)] will be updated by A[k] so that there will be more chance for this increasing sequence to grow longer. Therefore, we need to maintain all the maximal elements of increasing sequences with length from 1 to the current maximal length, i.e., the array M. OK, here is the c++ implementation.
- #include <iostream>
- using namespace std;
- // Return the Max Length of Increasing Subsequence (MLIS).
- int mlis(int* array, int n) {
- int maxlen = 1;
- int* lis = new int[n]; // lis[i] is the MLIS ending with array[i].
- for(int i = 0; i < n; ++i) {
- lis[i] = 1;
- }
- int* minmax = new int[n+1]; // minmax[i] is the minimal "max value" of subsequence with length i.
- minmax[0] = 0x80000000;
- minmax[1] = array[0];
- for(int i = 1; i < n; ++i) {
- int j;
- for(j = maxlen; j >= 0; --j) {
- if(array[i] > minmax[j]) {
- lis[i] = j + 1;
- break;
- }
- }
- if(lis[i] > maxlen) {
- maxlen = lis[i];
- minmax[lis[i]] = array[i];
- }
- else {
- minmax[j+1] = array[i];
- }
- }
- delete[] lis;
- delete[] minmax;
- return maxlen;
- }
- int main() {
- int array[10] = {3, -2, 2, 1, 5, 6, 3, 4, 8, 7};
- int maxlen = mlis(array, 10);
- cout << "max length: " << maxlen << endl;
- return 0;
- }
The command line prints:
max length: 5