Leetcode | 673. 最长递增子序列的个数

简介: Leetcode | 673. 最长递增子序列的个数

Leetcode | 673. 最长递增子序列的个数

题目信息

image.png

解题思路

这个题除了需要计算最长递增子序列的长度,还需要计算最长递增子序列的数量。

所以我们可以在存储每个位置最长递增子序列的长度的基础上,增加一个数组记录每个位置上最长递增子序列的数量。

例如我们在计算i位置上的最长子序列,假设num[i] > num[i-1],那么此时i位置上的最长递增子序列的长度应该是i-1位置上的子序列长度加一,那么此时i位置上最长递增子序列的数量应该和i-1位置上的子序列数量保持一致。

后面再和i-2位置上的数字比较时,假设num[i] > num[i-2],并且i-2i-1位置上的递增子序列的数量一致时,那么i位置上的最长递增子序列的数量应该是两者之和。

后面在i-3位置上的数字比较时,依次递推……

使用动态规划的思路解决这个题,状态转移的时候,有些地方需要多加注意如果i位置上的数字大于之前的数字时,出现递增子序列

  1. 如果此时的子序列长度大于已经有记录的子序列长度,则更新i位置的最长长度和重新统计i位置上最长递增子序列的数量
  2. 这个长度的递增子序列已经有记录,直接更新i位置上递增子序列的数量
  3. 最长递增子序列出现的位置不唯一,例如[1,2,3,1,2,3,1,2,3]

代码

public int findNumberOfLIS(int[] nums) {
    // 数组的长度
    int n = nums.length;
    // 记录每个位置上对应最长递增子序列的长度
    int[] status = new int[n];
    // 记录每个位置上对应最长递增子序列的个数
    int[] count = new int[n];
    // 每个长度的子序列对应的数量
    int[] ans = new int[2001];
    // 初始化操作,每个位置上的递增子序列长度和个数至少为1
    for (int i = 0; i < n; i++) {
        status[i] = 1;
        count[i] = 1;
    }
    // 统计全局最长的递增子序列的长度
    int max = 1;
    // 长度为1的递增子序列的个数就是数组的长度
    ans[1] = n;
    // 统计每个位置上最长递增子序列的长度和个数
    for (int i = 1; i < n; i++) {
        // 通过比较i位置上的数字和[0,i-1]位置上数字大小,计算递增子序列
        int k = i - 1;
        while (k >= 0) {
            // 如果i位置上的数字大时,出现递增子序列,
            // 1、如果此时的子序列长度大于已经有记录的子序列长度,则更新i位置的最长长度和重新统计i位置上最长递增子序列的数量
            // 2、这个长度的递增子序列已经有记录,直接更新i位置上递增子序列的数量
            if (nums[i] > nums[k] && status[k] + 1 > status[i]) {
                status[i] = status[k] + 1;
                // 更新最长长度时,递增子序列的长度也要重新计算
                count[i] = count[k];
                // 更新全局最长的递增子序列的长度
                max = Math.max(status[i], max);
                // 更新具有这个长度子序列的数量
                ans[status[i]] += count[i];
            } else if (nums[i] > nums[k] && status[k] + 1 == status[i]) {
                count[i] += count[k];
                ans[status[i]] += count[k];
            }
            --k;
        }
    }
    // 返回最长子串的数量
    return ans[max];
}

结果

image.png

目录
相关文章
|
3月前
|
Python
【Leetcode刷题Python】376. 摆动序列
文章提供了解决LeetCode "摆动序列" 问题的Python实现代码,通过遍历整数数组并使用两个变量 down 和 up 来记录正差和负差摆动序列的长度,最终返回最长摆动子序列的长度。
39 0
|
3月前
|
Python
【Leetcode刷题Python】946. 验证栈序列
LeetCode题目“946. 验证栈序列”的Python解决方案,通过模拟栈的压入和弹出操作来验证给定的两个序列是否能通过合法的栈操作得到。
29 6
|
3月前
|
算法 Python
【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
22 3
|
3月前
|
Python
【Leetcode刷题Python】105. 从前序与中序遍历序列构造二叉树
LeetCode上105号问题"从前序与中序遍历序列构造二叉树"的Python实现,通过递归方法根据前序和中序遍历序列重建二叉树。
25 3
|
3月前
|
算法 Python
【Leetcode刷题Python】300. 最长递增子序列
LeetCode 300题 "最长递增子序列" 的两种Python解决方案:一种使用动态规划,另一种使用贪心算法结合二分查找。
36 1
|
3月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
42 0
|
3月前
|
Python
【Leetcode刷题Python】674. 最长连续递增序列
LeetCode 674题 "最长连续递增序列" 的Python解决方案,使用动态规划算法找出给定整数数组中最长连续递增子序列的长度。
94 0
|
5月前
|
存储 算法 数据可视化
哈希表法快速求解最长连续序列 | 力扣128题详细解析
哈希表法快速求解最长连续序列 | 力扣128题详细解析
|
5月前
|
存储 算法
力扣经典150题第四十六题:最长连续序列
力扣经典150题第四十六题:最长连续序列
25 0
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行