
方法:动态规划
思路:
- 1.先根据动态规划的方程计算出最长的序列
- 1.1 先找是什么类型的动态规划:易发现是属于单串类型,属于依赖前方比i小的O(n)的子问题,可得到状态转移方程:f(i) = Max(f(i), f(i-1)+1, f(i-2)+1, ...)
- 1.2 根据状态转移方程写代码,可以得到最长的子序列的长度
- 2.存储每个位置(i)上的最长子序列由前方(i-1、i-2、...)的子序列组成的个数
- 3.根据一些特殊情况做处理
代码(JavaScript)
function findNumberOfLIS(nums) {
const dp = new Array(nums.length).fill(1);
const count = new Array(nums.length).fill(1);
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]) {
count[i] = count[j];
} else if(dp[j] + 1 == dp[i]) {
count[i] += count[j];
}
dp[i] = Math.max(dp[j] + 1, dp[i]);
}
}
}
const max = Math.max(...dp), index = dp.indexOf(max);
let result = 0, finalResult = 0;
for(let i = 0; i < dp.length; i++) {
if(dp[i] == max) {
result++;
finalResult += count[i];
}
}
if(result != 1) return finalResult;
return count[index];
};
let nums = [1, 3, 5, 4, 7];
console.log(findNumberOfLIS(nums));
nums = [2, 2, 2, 2, 2];
console.log(findNumberOfLIS(nums));
nums = [1,2,4,3,5,4,7,2];
console.log(findNumberOfLIS(nums));
nums = [1,2];
console.log(findNumberOfLIS(nums));
nums = [1,3,2];
console.log(findNumberOfLIS(nums));
nums = [1,3,2, 4, 3, 4];
console.log(findNumberOfLIS(nums));
nums = [1,1,1,2,2,2,3,3,3];
console.log(findNumberOfLIS(nums));