Coding problem · Medium · Dynamic Programming

Longest Increasing Subsequence

Medium Algorithms & data structures Seen at Google, Microsoft, Amazon

Given an integer array nums, return the length of the longest strictly increasing subsequence (elements in order, not necessarily contiguous).

Example 1

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

Example 2

Input: nums = [7,7,7,7]
Output: 1

Hints

Hint 1

O(n²) DP: lis[i] = 1 + max(lis[j]) for j < i with nums[j] < nums[i].

Hint 2

O(n log n): keep tails[k] = the smallest possible tail of an increasing subsequence of length k+1; binary-search where each number goes.

Write and run your solution

Loading the editor… (JavaScript is required to run code in your browser.)

Solution and explanation

Show the solution

Time O(n log n) · Space O(n)

Patience sorting: scan numbers and maintain tails, where tails[k] is the smallest tail of any increasing subsequence of length k + 1. For each x, find (binary search) the first tail >= x and replace it — or append if x is larger than all tails. The length of tails is the answer. (tails itself is not necessarily a valid subsequence.)

Reference solution

function lengthOfLIS(nums) {
  const tails = [];
  for (const x of nums) {
    let lo = 0, hi = tails.length;
    while (lo < hi) {
      const mid = (lo + hi) >> 1;
      if (tails[mid] < x) lo = mid + 1; else hi = mid;
    }
    tails[lo] = x;
  }
  return tails.length;
}