Number of Longest Increasing Subsequence
Problem
Given an integer array nums
, return the number of longest increasing subsequences.
Notice that the sequence has to be strictly increasing.
Example 1:
Input: nums = [1,3,5,4,7] Output: 2 Explanation: The two longest increasing subsequences are [1, 3, 4, 7] and [1, 3, 5, 7].
Example 2:
Input: nums = [2,2,2,2,2] Output: 5 Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is 1, so output 5.
Constraints:
1 <= nums.length <= 2000
-106 <= nums[i] <= 106
Solution
/**
* @param {number[]} nums
* @return {number}
*/
var findNumberOfLIS = function(nums) {
let max = 1; // overall max length of subsequence
let count = 1; // overall count of max length subsequence
const dp = [{ max, count }];
for (let i = 1; i < nums.length; i++) {
dp.push({ max: 1, count: 1 });
for (let j = 0; j < i; j++) {
if (nums[i] > nums[j]) { // can end at nums[i]
if (dp[i].max < dp[j].max + 1) { // new local max
dp[i].max = dp[j].max + 1;
dp[i].count = dp[j].count;
} else if (dp[i].max === dp[j].max + 1) { // same local max
dp[i].count += dp[j].count;
}
}
}
if (dp[i].max > max) { // new global max => new global count
max = dp[i].max;
count = dp[i].count;
} else if (dp[i].max === max) { // same global max => increment global count
count += dp[i].count;
}
}
return count;
};
We will implement a DP solution. Let dp[i]
have two properties, max
and count
. Let dp[i].max
be the length of the longest increasing subsequence ending at and including nums[i]
. Let dp[i].count
be the number of increasing subsequences of length dp[i].max
ending at and including nums[i]
.
- For the base case, if
i = 0
, thendp[0].max = 1
anddp[0].count = 1
since there's only1
possible subsequence which isnums[0]
itself. - For the recursive case,
dp[i].max
is computed the same way as the Longest Increasing Subsequence problem. Fordp[i].count
:- When we encounter a new subsequence with length greater than
dp[i].max
, we updatedp[i].count
to the count of the previous value in this new subsequence (ie.dp[i].count
will be reset todp[j].count
since the old count is no longer relevant for the new max length subsequence). - When we encounter a new subsequence with length same as
dp[i].max
, we incrementdp[i].count
by the count of the previous value in this new subsequence (ie.dp[i].count
will be incremented bydp[j].count
since the old count is still relevant).
- When we encounter a new subsequence with length greater than
Note that we also keep an overall max
and count
variable and update the two as needed after every i
(in a similar manner as the recursive case for dp
).