LeetCode刷题系列 -- 673. 最长递增子序列的个数

题目:

  

给定一个未排序的整数数组,找到最长递增子序列的个数。

示例 1:

输入: [1,3,5,4,7]
输出: 2
解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
示例 2:

输入: [2,2,2,2,2]
输出: 5
解释: 最长递增子序列的长度是1,并且存在5个子序列的长度为1,因此输出5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence
 

 

思路: 定义两个数组,分别为 dp (长度为 nums.length ) 与 count (长度为 nums.length ) ,

  其中,dp[ i ]  表示以 nums[ i ] 结尾的子序列的最大长度,  count[ i ]   表示以 nums[i] 结尾的长度为 dp[i]  的子序列的个数

  两重 for 循环,遍历nums 数组 

 第一重循环, 0 < i < nums.length

 第二重循环    0 < j < i 

  因为这里计算的是递增子序列,故而只考虑 num[ j ] < num[ i ]  情况

1) dp [ i ] < dp[ j ] + 1 

     dp[ i ] = dp[ j ] + 1

     count[ i ] = count[ j ]

2)  dp[ i ] == dp[ j] + 1

   count[ i ] += count[ j ] 

官方思路:

   https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/solution/dong-tai-gui-hua-dong-tu-fu-zhu-li-jie-ru-you-bang/

 

Java代码:

class Solution {
      int  findNumberOfLIS(int[]  nums){

        int[]  dp    = new int[nums.length];  // dp[i] 表示以 nums[i] 结尾的最长子序列的长度
        int[]  count = new int[nums.length]; // dp[i] 表示以 nums[i] 结尾的长度为dp[i] 的子序列的个数

        for(int i=0;i<nums.length;i++){
            dp[i] = 1;
            count[i] = 1;
        }

        int  max = 1; //子序列长度最小为 1

        for(int i=0;i<nums.length;i++){
            for(int j=0;j<i;j++){
                if(nums[j]<nums[i]){   // 要计算递增子序列,故而只考虑 num[j] < nums[i] 即可
                    if(dp[i]<dp[j] + 1){   // 若是以 nums[i] 为结尾的子序列长度 dp[i] 小于 dp[j] + 1 ,则更新 dp[i] = dp[j] + 1 ,count[i] = count[j]
                        dp[i] = dp[j] + 1;
                        count[i] = count[j];
                    }else if(dp[i] == dp[j] + 1){ // 若是以 nums[i] 为结尾的子序列长度 dp[i] 等于 dp[j] + 1 ,则更新 count[i] = count[j]
                        count[i] += count[j];
                    }
                }
                max = dp[i]>max?dp[i]:max;  // 更新最长子序列长度
            }
        }

        int result = 0;
        for(int i=0;i<nums.length;i++){
            if(max == dp[i]){
                result += count[i];  // 将所有最长长度的子序列的个数求和,可以重复
            }
        }


    return result;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值