0673-最长递增子序列的个数

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

示例 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位有符号整数。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence

参考:

python

# 0673.最长递增子序列的个数

class Solution:
    def findNumOfLIS(self, nums: [int]) -> int:
        """
        动态规划
        1.dp定义及下标
        - dp[i], i为下标的最长递增子序列的长度
        - count[i], nums[i]结尾的,最长递增子序列个数为count[i]
        2.递推公式
        两个维度,
        - 更新dp[i], if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1)
        - 更新count[i]
            - 在nums[i] > nums[j]前提下,如果在[0, i-1]的范围内,找到了j,使得dp[j] + 1 > dp[i],说明找到了一个更长的递增子序列。
                那么以j为结尾的子串的最长递增子序列的个数,就是最新的以i为结尾的子串的最长递增子序列的个数,即:count[i] = count[j]。
            - 在nums[i] > nums[j]前提下,如果在[0, i-1]的范围内,找到了j,使得dp[j] + 1 == dp[i],说明找到了两个相同长度的递增子序列。
                那么以i为结尾的子串的最长递增子序列的个数 就应该加上以j为结尾的子串的最长递增子序列的个数,即:count[i] += count[j]
        3.初始化
        - dp[i] = 1
        - count[i] = 1
        4.遍历顺序
        - 外层for 1->length-1
        - 内层for 0, i-1
        :param nums:
        :return:
        """
        length = len(nums)
        if length <= 1: return length
        dp = [1 for i in range(length)]
        count = [1 for i in range(length)]
        maxCnt = 0
        for i in range(1, length):
            for j in range(i):
                if nums[i] > nums[j]:
                    if dp[j] + 1 > dp[i]:
                        dp[i] = dp[j] + 1
                        count[i] = count[j]
                    elif dp[j] + 1 == dp[i]:
                        count[i] += count[j]
                if dp[i] > maxCnt:
                    maxCnt = dp[i]
        res = 0
        for i in range(length):
            if maxCnt == dp[i]:
                res += count[i]
        return res

golang

package dynamicPrograming

// 动态规划
func findNumberOfLIS(nums []int) int {
	length := len(nums)
	if length <= 1 {
		return length
	}
	dp := make([]int, length)
	count := make([]int, length)
	for i := range dp {
		dp[i] = 1
		count[i] = 1
	}
	maxCnt := 0
	for i:=1;i<length;i++ {
		for j:=0;j<i;j++ {
			if nums[i] > nums[j] {
				if dp[j] +1 > dp[i] {
					dp[i] = dp[j] + 1
					count[i] = count[j]
				} else if dp[j] + 1 == dp[i] {
					count[i] += count[j]
				}
			}
			if dp[i] > maxCnt {
				maxCnt = dp[i]
			}
 		}
	}
	res := 0
	for i := range dp {
		if maxCnt == dp[i] {
			res += count[i]
		}
	}
	return res
}

posted on 2021-12-05 11:32  进击的davis  阅读(57)  评论(0编辑  收藏  举报

导航