思路分析:
-
动态规划数组: 使用两个动态规划数组
dp
和thesame
来记录信息。dp[i]
表示以第i
个元素为结尾的最长递增子序列的长度。thesame[i]
表示以第i
个元素为结尾的最长递增子序列的个数。
-
初始化: 初始时,将
dp
数组全部初始化为1,表示每个元素自身构成的递增子序列的长度为1,同时thesame
数组全部初始化为1。 -
动态规划更新: 遍历数组元素,对于每个元素
nums[i]
,再遍历其前面的元素nums[j]
。- 如果
nums[i] > nums[j]
,说明当前元素可以加入以nums[j]
为结尾的递增子序列,此时有两种情况:- 如果
dp[i] == dp[j] + 1
,说明加入当前元素后的长度仍然等于以nums[j]
为结尾的递增子序列的长度,因此累加thesame[j]
。 - 如果
dp[i] < dp[j] + 1
,说明加入当前元素后的长度变为更长的递增子序列,更新dp[i]
和thesame[i]
。
- 如果
- 如果
-
最长递增子序列的长度: 在动态规划过程中,通过不断更新
longmax
来记录最长递增子序列的长度。 -
统计最长递增子序列个数: 最后遍历一次数组,统计长度为
longmax
的递增子序列的个数,累加到变量num
中。 -
返回结果: 返回最终的
num
,即以最长递增子序列长度为longmax
的子序列个数。
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
// dp数组用于存储以nums[i]为结尾的最长递增子序列的长度
vector<int> dp(nums.size(), 1);
// i、j为循环变量,longmax用于记录最长递增子序列的长度,thesame用于记录以nums[i]为结尾的最长递增子序列的个数
int i, j, longmax = 1;
vector<int> thesame(nums.size(), 1);
thesame[0] = 1;
// 外层循环遍历数组元素,内层循环用于比较前面的元素,更新dp和thesame数组
for (i = 1; i < nums.size(); i++) {
for (j = i - 1; j >= 0; j--) {
// 如果当前元素nums[i]大于前面的元素nums[j]
if (nums[i] > nums[j]) {
// 如果当前长度dp[i]等于dp[j]+1,则累加thesame[j]
if (dp[i] == dp[j] + 1)
thesame[i] += thesame[j];
// 如果当前长度dp[i]小于dp[j]+1,则更新dp[i]和thesame[i]
if (dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1;
thesame[i] = thesame[j];
}
}
}
// 更新最长递增子序列的长度
longmax = max(longmax, dp[i]);
}
// 统计最长递增子序列长度为longmax的个数
int num = 0;
for (i = 0; i < nums.size(); i++) {
if (longmax == dp[i])
num += thesame[i];
}
return num;
}
};