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

Description:

Given an unsorted array of integers, find the 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].

Example 2:

Input: [2,2,2,2,2]
Output: 5
Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is 1, so output 5.

Note: Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int.


问题描述

给定一串未排序的整数,返回最长递增子序列的数目


问题分析

先想想看如何找到一个最长递增序列的长度
通过动态规划,转换为若nums[i] > nums[j],dp[i] = dp[j] + 1 0 <= j < i

现在问题是求最长递增序列的个数,我们维护两个数组

  1. length[i],存放以i为递增序列尾部元素的最长序列长度(注意是最长序列)
  2. count[i],存放以i为递增序列尾部元素的最长序列个数(注意是最长序列)

我们需要在迭代数组时维护这两个数组,并且通过这两个数组累加最长序列个数
如何累加?
令当前最长序列长度为maxlen,令当前最长序列个数为maxcount
当maxlen == length[i] 时,maxcount += count[i]
当maxlen < length[i]时,maxlen = length[i],maxcount = count[i]


解法:

class Solution {
    public int findNumberOfLIS(int[] nums) {
        int n = nums.length, res = 0, max_len = 0;
        int[] len =  new int[n], cnt = new int[n];

        for(int i = 0; i < n; i++){
            //一定要注意这里的初始化
            len[i] = cnt[i] = 1;
            for(int j = 0; j < i ; j++){
                if(nums[i] > nums[j]){
                    if(len[i] == len[j] + 1)    cnt[i] += cnt[j];
                    if(len[i] < len[j] + 1){
                        len[i] = len[j] + 1;
                        cnt[i] = cnt[j];
                    }
                }
            }
            if(max_len == len[i])   res += cnt[i];
            if(max_len < len[i]){
                max_len = len[i];
                res = cnt[i];
            }
        }

        return res;
    }
}

你可能感兴趣的:(算法与数据结构,leetcode全解)