Leetcode算法学习日志-673 Number of Longest Increasing Subsequence

这篇博客介绍了LeetCode 673问题,即寻找给定无序整数数组中最长递增子序列的个数。通过动态规划方法,分析了如何使用两个数组L和M分别记录以每个元素结尾的最长递增序列长度和个数,最终解决此问题的C++代码实现。
摘要由CSDN通过智能技术生成

Leetcode 673 Number of Longest Increasing Subsequence

题目原文

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.

题意分析

本题可以分解为一个更简单的问题,寻找最长递增序列的长度,这个问题可以采用动态规划方法,令一个数组L[N],L[i]表示以nums[i]结尾的最大递增序列的长度。要注意原序列可能有多个长度达到最长的递增子序列,每个序列一定以nums中某个元素为结尾。

解法分析

本题采用自底向上动态规划方法,首先解决最长递增序列长度的问题,用L[N]存储以nums每一位结尾的递增子序列的最长长度,递归式如下:


为了在最后能得到最长序列的个数,需要利用另一个数组M[N]存储以nums[i]结尾的最长序列的个数。C++代码如下:

class Solution {
public:
    int findNumberOfLIS(vector<int>& nums) {
        int n=nums.size();
        if(n==0)
            return 0;
        vector<int> L(n,1);//L[i] is the length of the longest substr that contains nums[i]
        vector<int> M(n,1);//M[i] is the number of str end with nums[i] and the length reaches L[i];
        int i,j;
        int temp=1;
        for(i=0;i<n;i++){
            for(j=0;j<i;j++){
                if(nums[j]<nums[i]){
                    temp=L[j]+1;
                    if(temp==L[i])
                        M[i]=M[i]+M[j];//That is important
                    else if(temp>L[i]){
                        M[i]=M[j];//That is important
                        L[i]=temp;  
                    }      
                }
                else
                    continue;
            }
        }
        //Find the max number in nums,and its count  
        int count=1;
        int maxL=0;
        for(i=0;i<n;i++){
            if(maxL<L[i]){
                count=M[i];
                maxL=L[i];  
            }
                
            else if(maxL==L[i])
                count=count+M[i];
        }
        return count;   
    }
};
if(nums[j]<nums[i]){
                    temp=L[j]+1;
                    if(temp==L[i])
                        M[i]=M[i]+M[j];//That is important
                    else if(temp>L[i]){
                        M[i]=M[j];//That is important
                        L[i]=temp;  
                    }      
                }
上述代码最关键,原因是以某元素a结尾的递增序列可能有n个,如果有一个元素b满足b>a,则对于以a结尾的最长递增序列,由a贡献的序列个数为n;不同元素结尾的最长序列长度可能相同,在计算相应长度序列个数时应把这些都考虑在内。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值