算法日常・每日刷题--<动态规划>29

673. 最长递增子序列的个数 - 力扣(LeetCode)

目描述

给定一个未排序的整数数组 nums,返回最长递增子序列的个数。 注意:序列要求严格递增,子序列不要求连续。

示例 1: 输入:nums = [1,3,5,4,7] 最长递增子序列长度为 3,一共有 2 个:[1,3,5,7]、[1,3,4,7] 输出:2

示例 2: 输入:nums = [2,2,2,2,2] 最长递增子序列长度为 1,一共 5 个 输出:5

解题思路

本题是最长递增子序列 LIS 的变形题。普通 LIS 只需要求最长长度,本题额外要求统计有多少条这样的最长序列。

状态定义

  • len[i]:以 nums[i] 结尾的最长递增子序列的长度
  • count[i]:以 nums[i] 结尾,长度等于len[i] 的递增子序列的数量

初始条件: 每个元素自身单独就可以构成长度为 1 的子序列。 所以:len[i] = 1,count[i] = 1。

状态转移

遍历 i 作为子序列的结尾,再用 j 遍历 i 前面所有元素(j < i):

  1. 当 nums[i] > nums[j],说明nums[i]可以接在以nums[j]结尾的子序列后面
    • 若 len[j]+1 > len[i]:找到更长的子序列。更新长度len[i],方案数继承count[j]
    • 若 len[j]+1 == len[i]:发现同样长度 的新路径,方案数累加 count[i] += count[j]

统计全局答案

维护两个全局变量:

  • maxLen:整个数组最长递增子序列的长度
  • ans:最长递增子序列总个数 每次计算完len[i]后:
  1. 如果 len[i] > maxLen:发现了更长序列,更新maxLen,重置ans = count[i]
  2. 如果 len[i] == maxLen:当前结尾的子序列也是最长,ans += count[i]
cpp 复制代码
class Solution {
public:
    int findNumberOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> len(n, 1);
        vector<int> count(n, 1);
        int maxLen = 1;
        int ans = 1;
        for (int i = 1; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                if (nums[i] > nums[j]) {
                    if (len[j] + 1 > len[i]) {
                        len[i] = len[j] + 1;
                        count[i] = count[j];
                    } else if (len[j] + 1 == len[i]) {
                        count[i] += count[j];
                    }
                }
            }
            if (len[i] > maxLen) {
                maxLen = len[i];
                ans = count[i];
            } else if (len[i] == maxLen) {
                ans += count[i];
            }
        }
        return ans;
    }
};
相关推荐
其实防守也摸鱼19 小时前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
Nuanyt20 小时前
LeetCode Hot 100 链表专题(五)· 2 题(Java)
java·算法·leetcode·链表
w_zero_one1 天前
递归算法(一)
java·开发语言·算法
圣保罗的大教堂1 天前
leetcode 3736. 最小操作次数使数组元素相等 III 简单
leetcode
文丑颜不良啊1 天前
LeetCode1881~1990题目解析
java·leetcode
风影同志783241 天前
20 个比特能装下多少行情?——实测拆解 Kronos 的 K 线分词器
算法
写的都是BUG1 天前
APK 里的钥匙,一直就放在门口:聊聊加固真正该做什么
前端·算法
地平线开发者1 天前
CLIP 的零样本分类:一组文本如何变成图像分类器?
算法
京东云开发者1 天前
从“会生成”到“能生产”:萤火虫 AIGC 平台的 AI Infra 实践
算法·aigc·产品