力扣--动态规划673.最长递增子序列的个数

思路分析:

  1. 动态规划数组: 使用两个动态规划数组 dpthesame 来记录信息。

    • dp[i] 表示以第 i 个元素为结尾的最长递增子序列的长度。
    • thesame[i] 表示以第 i 个元素为结尾的最长递增子序列的个数。
  2. 初始化: 初始时,将 dp 数组全部初始化为1,表示每个元素自身构成的递增子序列的长度为1,同时 thesame 数组全部初始化为1。

  3. 动态规划更新: 遍历数组元素,对于每个元素 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]
  4. 最长递增子序列的长度: 在动态规划过程中,通过不断更新 longmax 来记录最长递增子序列的长度。

  5. 统计最长递增子序列个数: 最后遍历一次数组,统计长度为 longmax 的递增子序列的个数,累加到变量 num 中。

  6. 返回结果: 返回最终的 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;
    }
};

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值