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

来源:互联网 发布:ipcms录像软件 编辑:程序博客网 时间:2024/06/14 07:52

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: 2Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7].

Example 2:

Input: [2,2,2,2,2]Output: 5Explanation: 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;不同元素结尾的最长序列长度可能相同,在计算相应长度序列个数时应把这些都考虑在内。

阅读全文
0 0
原创粉丝点击