☰ All problems

Longest Increasing Subsequence

A hiking app records the elevation, in metres, at each checkpoint of a route in nums; checkpoints below sea level have negative elevations. For its "best climb" badge it looks for the longest selection of checkpoints, kept in route order but allowed to skip any checkpoints in between, in which every chosen checkpoint is strictly higher than the one before it.

Return the length of that longest strictly increasing subsequence of nums. For example, [2,5,9] is a valid selection from [2,7,5,1,9], while [7,5] is not, because it goes down.

Example 1
Input: nums = [3,8,4,5,1,9]
Output: 4

Explanation: Picking 3, 4, 5, 9 climbs at every step, and no selection of five checkpoints does.

Example 2
Input: nums = [-2,-7,-1,0,-3]
Output: 3

Explanation: Both -2, -1, 0 and -7, -1, 0 have length 3.

Example 3
Input: nums = [9,6,4,2]
Output: 1

Explanation: The route only goes down, so the best selection is a single checkpoint.

Constraints

  • nums has between 1 and 2500 checkpoints.
  • Each elevation is an integer from -10^4 to 10^4.

Follow-up: Can you also reconstruct one longest subsequence, not just its length?

💡 Hint 1

An O(n²) DP works: len[i] = 1 + the largest len[j] with j < i and nums[j] < nums[i].

💡 Hint 2

For O(n log n), keep tails[k] = the smallest possible last value of an increasing subsequence of length k + 1. This array is always sorted.

💡 Hint 3

For each number, binary-search the first tail that is >= it and overwrite it (or append if none). The final length of tails is the answer.

/**
 * @param {number[]} nums
 * @return {number}
 */
function lengthOfLIS(nums) {

}
Ctrl/⌘ + ' run · Ctrl/⌘ + Enter submit
esc