老晨Leetcode 673 最长升序子序列的个数 · Number of Longest Increasing Subsequence

给定一个无序的整数序列,找到最长的升序子序列的个数。
Example 1:
Input: [1,3,5,4,7]
Output: 2
Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7].

这道题很明显是用动态规划做,当你处理到nums[i]这个数的时候,只需要保留以这个数结尾的最长子序列的情况,不需要保留短的,比如说上例算到5的时候,
1,3,5最长
1,5
3,5这两个序列是可以直接忽略的。因为对于后面的数来说,如果要你(5这个数),肯定是要用上你最长的(不然我就要别人了,比如说4),才能拼成最长的子序列

然而你试着用f[i] 表示以nums[i]结尾的子序列的长度/个数, 会发现存一个数是不够的,所以需要两个dp数组
int[] len = new int[n];//len 以nums[i]结尾的最长子序列多长
int[] c = new int[n];//count 以nums[i]结尾的最长子序列个数

这是一种常见的处理方法,需要掌握

//经典,必须会掌握
    public int findNumberOfLIS(int[] nums) {
        if(nums.length == 0) return 0;
        int n = nums.length;
        int[] len = new int[n];//len 以i结尾的最长子序列多长
        int[] c = new int[n];//count 以i结尾的最长子序列个数
        int max = 0;//全局最长子序列有多长
        for(int i = 0 ; i<n; i++) {
            len[i] = 1; c[i] = 1;
            for(int j = 0; j < i; j++){
                if(nums[j] >= nums[i]){
                    continue;
                }
                if(len[j] + 1 == len[i]) {
                    c[i] += c[j]; //易错点!!
                } else if(len[j] + 1 > len[i]) {
                    c[i] = c[j];
                    len[i] = len[j] + 1;
                }
            }
            max = Math.max(max, len[i]);
        }
        int res = 0;
        for(int i = 0; i<n;i++) {
            if(len[i] == max) {
                res+= c[i];
            }
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值