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 }
相關文章
相關標籤/搜索