673. Number of Longest Increasing Subsequence

87 篇文章 0 订阅

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.

思路:DP,先求最大的递增连续序列的个数,然后再DP到i位置位置形成j个连续子序列的个数

第二次DP要利用第一个DP数组求出来的信息 

package l673;
class Solution {
    public int findNumberOfLIS(int[] nums) {
    	if(nums.length == 0)	return 0;
        int max = 1;
        int[] dp1 = new int[nums.length];
        dp1[0] = 1;
        for(int i=1; i<nums.length; i++) {
        	dp1[i] = 1;
        	for(int j=0; j<i; j++)
        		if(nums[i] > nums[j])
        			dp1[i] = Math.max(dp1[i], 1+dp1[j]);
        	max = Math.max(max, dp1[i]);
        }
        
        int[][] dp = new int[nums.length][1+max];
        for(int i=0; i<nums.length; i++)	dp[i][0]=1;
        dp[0][1] = 1;
        for(int i=1; i<nums.length; i++) {
        	for(int j=0; j<i; j++) {
        		dp[i][1] = 1;
        		for(int k=1; k<max; k++) {
        			if(nums[i] > nums[j])
        				dp[i][k+1] += dp[j][k];
    			}
        	}
        }
        
        int ret = 0;
        for(int i=0; i<nums.length; i++)
        	ret += dp[i][max];
        return ret;
    }
}

这个是O(N^3)的,用Python会TLE,其实后一过程可以优化为O(N^2),dp2[i]表示以i结尾,LIS长度为dp[i]的个数

class Solution(object):
    def findNumberOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums: return 0
        n = len(nums)
        Max_len = 0
        # max_len[i]:max LIS length end with i, cnt[i]:count of current longest LIS length end with i 
        max_len, cnt = [0]*n, [0]*n
        
        for i in range(n):
            max_len[i] = 1
            for j in range(i):
                if nums[i]>nums[j]:
                    max_len[i] = max(max_len[i], max_len[j]+1)
            Max_len = max(Max_len, max_len[i])
        
        for i in range(n):
            if max_len[i]==1: 
                cnt[i]=1
                continue
            for j in range(i):
                if nums[i]>nums[j]:
                    if max_len[i] == max_len[j]+1:
                        cnt[i] += cnt[j]
                        
        return sum(cnt[i] for i in range(n) if max_len[i]==Max_len)

s=Solution()
print(s.findNumberOfLIS([2,2,2,2,2]))
print(s.findNumberOfLIS([1,3,5,4,7]))
print(s.findNumberOfLIS([1,3,2]))
然后2个循环可以写在一起

class Solution(object):
    def findNumberOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        cur_max = ret = 0
        # max_len[i]:max LIS length end with i, cnt[i]:max count of current max LIS length 
        max_len, cnt = [0]*n, [0]*n
        
        for i in range(n):
            max_len[i] = cnt[i] = 1
            for j in range(i):
                if nums[i]>nums[j]:
                    if max_len[i]==max_len[j]+1: cnt[i]+=cnt[j]
                    elif max_len[i]<max_len[j]+1:   # max LIS max_length at position i have changed because of j
                        max_len[i] = max_len[j]+1
                        cnt[i] = cnt[j]
                    
            # current max may change
            if cur_max == max_len[i]: ret += cnt[i]
            elif cur_max<max_len[i]:
                ret = cnt[i]
                cur_max = max_len[i]
        
        return ret

s=Solution()
print(s.findNumberOfLIS([1,3,5,4,7]))
print(s.findNumberOfLIS([1,3,2]))





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值