DrawCode Algorithm Visualizer • Dynamic Programming • Medium

Longest Increasing Subsequence (LIS)

Tags: DP, Binary Search, LIS, Arrays

1. One-Liner

LIS finds the maximum length of a strictly increasing subsequence—classic O(n²) DP or O(n log n) with tails + binary search.


2. The Problem It Solves

From an array, pick indices i1 < i2 < … with a[i1] < a[i2] < … of maximum length—used in analytics, scheduling, and as a building block for harder DP.


3. The Core Idea

DP view: dp[i] = LIS ending at i. Efficient view: keep smallest tail for each length; replace with binary search—Patience Sorting trick.


4. How It Works (Step-by-Step)

StepWhat Happens
1. Naive DPFor each i, scan j<i with a[j]<a[i]
2. Patiencetails sorted; for x, lower_bound replace
3. Answertails size

5. Dry Run Example

[10,9,2,5,3,7,101,18] → LIS length 4 (e.g. 2,5,7,101).


6. Key Properties

PropertyValue
Best timeO(n log n)
ReconstructionParent pointers optional

7. Where It Is Used

DomainUse
DataTrend extraction
AlgorithmsDilworth, box stacking variants

8. Interview Tips

Derive tails invariant, prove binary search placement, mention non-decreasing variant tweak (<=).


9. Comparison with Other Algorithms

ApproachTime
DPO()
Patience + BSO(n log n)

10. Complexity

MetricValue
TimeO(n log n) optimal
SpaceO(n)

Implementation Example (PYTHON)

import bisect

def lis_length(nums: list[int]) -> int:
    tails: list[int] = []
    for x in nums:
        i = bisect.bisect_left(tails, x)
        if i == len(tails):
            tails.append(x)
        else:
            tails[i] = x
    return len(tails)

Interactive Visualizer Workspace

Explore step-by-step interactive animations, memory state tracking, and live multi-language execution in DrawCode.

Launch Interactive Visualizer