Leetcode 673.最长递增子序列的个数

最长递增子序列的个数

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

示例 1: 数组

输入: [1,3,5,4,7] spa

输出: 2 code

解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。 blog

示例 2: 排序

输入: [2,2,2,2,2] io

输出: 5 class

解释: 最长递增子序列的长度是1,而且存在5个子序列的长度为1,所以输出5。 import

注意: 给定的数组长度不超过 2000 而且结果必定是32位有符号整数。 遍历

 

思路

定义 dp(n,1) cnt (n,1)

 

这里我用dp[i]表示以nums[i]为结尾的递推序列的长度,用cnt[i]表示以nums[i]为结尾的递推序列的个数,初始化都赋值为1,只要有数字,那么至少都是1。而后咱们遍历数组,对于每一个遍历到的数字nums[i],咱们再遍历其以前的全部数字nums[j],当nums[i]小于等于nums[j]时,不作任何处理,由于不是递增序列。反之,则判断dp[i]和dp[j]的关系,若是dp[i]等于dp[j] + 1,说明nums[i]这个数字能够加在以nums[j]结尾的递增序列后面,而且以nums[j]结尾的递增序列个数能够直接加到以nums[i]结尾的递增序列个数上。若是dp[i]小于dp[j] + 1,说明咱们找到了一条长度更长的递增序列,那么咱们此时奖dp[i]更新为dp[j]+1,而且本来的递增序列都不能用了,直接用cnt[j]来代替。维护一个全局最长的子序列长度mx,每次都进行更新,到最后遍历一遍每一个节点,若是长度等于mx,res+=cnt[i];

 
 1 import java.util.Arrays;
 2 
 3 class Solution {
 4     public int findNumberOfLIS(int[] nums) {
 5         int n=nums.length;
 6         int max_len=1;
 7         int res=0;
 8         int[] dp=new int[n];
 9         int[] cnt=new int[n];
10         Arrays.fill(dp,1);
11         Arrays.fill(cnt,1);
12         for(int i=1;i<n;i++){
13             for(int j=0;j<i;j++){
14                 if(nums[j]<nums[i]&&dp[j]+1>dp[i]){
15                     dp[i]=dp[j]+1;
16                     cnt[i]=cnt[j];
17                 }else if(nums[j]<nums[i]&&dp[j]+1==dp[i]){
18                     cnt[i]+=cnt[j];
19                 }
20             }
21             max_len=Math.max(max_len,dp[i]);
22         }
23         for(int i=0;i<n;i++){
24             if(dp[i]==max_len) res+=cnt[i];
25         }
26         return res;
27     }
28 }
相关文章
相关标签/搜索