Algo Algo   C++   C#   Demo   JS   Py   SQL   Stat   TA

Sequence : Longest Increasing Subsequence

O(n log n) Tracking "best" subsequences of each length from 1 to "length". "tail" (sorted) - the ends of "best" subsequences. "prev" - the predecessors of items of "best" subsequences. "length" - length of longest "best" subsequence.

// -----------------------------------------------------------------------------
// Longest Increasing Subsequence                                            C++
// -----------------------------------------------------------------------------
std::vector<int> LIS(std::vector<int> &a)
{
    int n = a.size();
    std::vector<int> prev(n);
    std::vector<int> tail(n + 1);
    int length = 0;
    for (int i = 0; i < n; i++) {
        int low = 1;
        int high = length;
        while (low <= high) {
            int mid = (low + high + 1) / 2;
            if (a[tail[mid]] < a[i])
                low = mid + 1;
            else
                high = mid - 1;
        }
        int pos = low;
        prev[i] = tail[pos - 1];
        tail[pos] = i;
        if (pos > length) length = pos;
    }
    std::vector<int> lis(length);
    int k = tail[length];
    for (int j = length - 1; j >= 0; j--) {
        lis[j] = a[k];
        k = prev[k];
    }
    return lis;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Longest Increasing Subsequence                                             C#
// -----------------------------------------------------------------------------
static int[] LIS(int[] a)
{
    int n = a.Length;
    int[] prev = new int[n];
    int[] tail = new int[n + 1];
    int length = 0;
    for (int i = 0; i < n; i++) {
        int low = 1;
        int high = length;
        while (low <= high) {
            int mid = (low + high + 1) / 2;
            if (a[tail[mid]] < a[i])
                low = mid + 1;
            else
                high = mid - 1;
        }
        int pos = low;
        prev[i] = tail[pos - 1];
        tail[pos] = i;
        if (pos > length) length = pos;
    }
    int[] lis = new int[length];
    int k = tail[length];
    for (int j = length - 1; j >= 0; j--) {
        lis[j] = a[k];
        k = prev[k];
    }
    return lis;
}
// -----------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Longest Increasing Subsequence                                          Python
# ------------------------------------------------------------------------------
def LIS(a):
    n = len(a)
    prev = [0] * n
    tail = [0] * (n + 1)
    length = 0
    for i in range(n):
        low = 1
        high = length
        while low <= high:
            mid = (low + high + 1) // 2
            if a[tail[mid]] < a[i]:
                low = mid + 1
            else:
                high = mid - 1
        pos = low
        prev[i] = tail[pos - 1]
        tail[pos] = i
        if pos > length:
            length = pos
    lis = [0] * length
    k = tail[length]
    for i in range(length)[::-1]:
        lis[i] = a[k]
        k = prev[k]
    return lis
# ------------------------------------------------------------------------------
Algo Algo   C++   C#   Demo   JS   Py   SQL   Stat   TA