AlgoLab
AlgorithmsCompare
AlgoLab
AlgorithmsCompareGitHub

© 2026 AlgoLab. Open source.

AlgorithmsDynamic ProgrammingLongest Increasing Subsequence
Dynamic Programmingintermediatesubsequencebinary-searchpatience-sorting

Longest Increasing Subsequence

The Longest Increasing Subsequence (LIS) problem finds the length of the longest subsequence where each element is strictly greater than the previous. The O(n²) DP solution fills dp[i] = length of LIS ending at index i. The O(n log n) patience sorting approach uses binary search and a patience piles array.

Complexity

Best
O(n log n)
Average
O(n log n)
Worst
O(n log n)
Space
O(n)

Visualizer

Implementation

int lis(vector<int>& arr) {
    vector<int> piles;
    for (int x : arr) {
        auto it = lower_bound(piles.begin(), piles.end(), x);
        if (it == piles.end()) piles.push_back(x);
        else *it = x;
    }
    return piles.size();
}

How It Works

1.O(n²) DP

dp[i] = length of LIS ending at index i. For each i, look at all j<i where arr[j]<arr[i]: dp[i]=max(dp[j]+1). Answer is max(dp). Simple but O(n²).

2.Patience Sorting O(n log n)

Maintain an array piles where piles[k] = smallest tail of all increasing subsequences of length k+1. For each element, binary search for its position in piles. Length of piles = LIS length.

3.Why Patience Sorting Works

Piles stay sorted because each new element is placed at the leftmost pile whose top is >= it. The number of piles equals the LIS length by a beautiful combinatorial argument (Dilworth's theorem).

Related Algorithms

LayoutGridLongest Common SubsequenceLayoutGrid0/1 KnapsackLayoutGridFibonacci (DP)

Test Your Knowledge

Quiz coming soon for this algorithm.

Back to all algorithms