← DSA
MEDIUM

Longest Increasing Subsequence

PracticeNeetCode ↗LeetCode ↗

Given an integer array nums, return the length of the longest strictly increasing subsequence — elements don't need to be contiguous, just in increasing order and appearing in their original relative order.

Example

Input nums = [10,9,2,5,3,7,101,18]
Output 4

Key Pointers

Step-by-Step Analysis

  1. Initialize dp as an array of 1s (every element is, at minimum, a subsequence of length 1 on its own).
  2. For each index i from 1 to n−1: for each earlier index j from 0 to i−1, if nums[j] < nums[i], update dp[i] = max(dp[i], dp[j] + 1).
  3. Track the running maximum of dp as it's computed, or take max(dp) once the loops finish.
  4. Return that maximum.

Complexity

Time: O(n²) — Space: O(n)

Code

def lengthOfLIS(nums: list[int]) -> int:
    dp = [1] * len(nums)

    for i in range(1, len(nums)):
        for j in range(i):
            if nums[j] < nums[i]:
                dp[i] = max(dp[i], dp[j] + 1)

    return max(dp)

Code Explanation

How the solution above works, piece by piece.

  1. dp[i] = length of the longest increasing subsequence that ends with nums[i]. Every element alone gives 1.
  2. For each earlier j with nums[j] < nums[i], nums[i] can extend that chain: dp[j] + 1.
  3. Keep the best such extension.
  4. The answer is the largest dp value, since the longest chain can end anywhere.
  5. O(n²) time, O(n) space (a binary-search version gets O(n log n)).

Visual Walkthrough

Running it on nums = [10, 9, 2, 5, 3, 7, 101, 18]:

LIS dp values with one longest chainnums10091225334751016187dp11122344dp[i] = longest increasing subsequence that ends at ie.g. 2 → 3 → 7 → 101 has length 4 = max(dp)
Each dp[i] looks back at every smaller earlier number and extends the best chain ending there. 101 and 18 both end chains of length 4 (2, 3, 7 then 101 or 18), so the answer is 4.
one longest chaindp = 4

Video Explanation

NeetCode — Dynamic Programming, LeetCode 300