原题链接
动态规划
思路与算法
定义 表示以 结尾的最长上升子序列的长度, 表示以 结尾的最长上升子序列的个数。设 的最长上升子序列的长度为 ,那么答案为所有满足 的 所对应的 之和。
我们从小到大计算 数组的值,在计算 之前,我们已经计算出 的值,则状态转移方程为:
即考虑往 中最长的上升子序列后面再加一个 。由于 代表 中以 结尾的最长上升子序列,所以如果能从 这个状态转移过来,那么 必然要大于 ,才能将 放在 后面以形成更长的上升子序列。
对于 ,其等于所有满足 的 之和。在代码实现时,我们可以在计算 的同时统计 的值。
复杂度分析
时间复杂度:,其中 是数组 的长度。
空间复杂度:。
typescript
function findNumberOfLIS(nums: number[]): number {
const dp = new Array(nums.length).fill(1);
const count = new Array(nums.length).fill(1);
let maxLen = 0;
let ans = 0;
for(let i = 0; i < nums.length; i++) {
for(let j = 0; j < i; j++) {
if(nums[j] < nums[i]) {
if(dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1; // 原始 dp 的转移方程
count[i] = count[j];
} else if(dp[j] + 1 === dp[i]) {
count[i] += count[j];
}
}
}
if(dp[i] > maxLen) {
maxLen = dp[i];
ans = count[i];
} else if(dp[i] === maxLen){
ans += count[i];
}
}
return ans;
};