1. 程式人生 > >Leetcode 673.最長遞增子序列的個數

Leetcode 673.最長遞增子序列的個數

mat font nbsp 排序 最長遞增子序列 超過 個數 strong 所有

最長遞增子序列的個數

給定一個未排序的整數數組,找到最長遞增子序列的個數。

示例 1:

輸入: [1,3,5,4,7]

輸出: 2

解釋: 有兩個最長遞增子序列,分別是 [1, 3, 4, 7] 和[1, 3, 5, 7]。

示例 2:

輸入: [2,2,2,2,2]

輸出: 5

解釋: 最長遞增子序列的長度是1,並且存在5個子序列的長度為1,因此輸出5。

註意: 給定的數組長度不超過 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 }

Leetcode 673.最長遞增子序列的個數