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.

这道题给了我们一个数组,让求最长递增序列的个数,题目中的两个例子也很好的说明了问题。那么对于这种求极值的问题,直觉告诉我们应该要使用动态规划 Dynamic Programming 来做。其实这道题在设计 DP 数组的时候有个坑,如果将 dp[i] 定义为到i位置的最长子序列的个数的话,则递推公式不好找。但是如果将 dp[i] 定义为以 nums[i] 为结尾的递推序列的个数的话,再配上这些递推序列的长度,将会比较容易的发现递推关系。这里用 len[i] 表示以 nums[i] 为结尾的递推序列的长度,用 cnt[i] 表示以 nums[i] 为结尾的递推序列的个数,初始化都赋值为1,只要有数字,那么至少都是1。然后遍历数组,对于每个遍历到的数字 nums[i],再遍历其之前的所有数字 nums[j],当 nums[i] 小于等于 nums[j] 时,不做任何处理,因为不是递增序列。反之,则判断 len[i] 和 len[j] 的关系,如果 len[i] 等于 len[j] + 1,说明 nums[i] 这个数字可以加在以 nums[j] 结尾的递增序列后面,并且以 nums[j] 结尾的递增序列个数可以直接加到以 nums[i] 结尾的递增序列个数上。如果 len[i] 小于 len[j] + 1,说明找到了一条长度更长的递增序列,那么此时将 len[i] 更新为 len[j]+1,并且原本的递增序列都不能用了,直接用 cnt[j] 来代替。在更新完 len[i] 和 cnt[i] 之后,要更新 mx 和结果 res,如果 mx 等于 len[i],则把 cnt[i] 加到结果 res 之上;如果 mx 小于 len[i],则更新 mx 为 len[i],更新结果 res 为 cnt[i],参见代码如下:

解法一:

class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int res = , mx = , n = nums.size();
vector<int> len(n, ), cnt(n, );
for (int i = ; i < n; ++i) {
for (int j = ; j < i; ++j) {
if (nums[i] <= nums[j]) continue;
if (len[i] == len[j] + ) cnt[i] += cnt[j];
else if (len[i] < len[j] + ) {
len[i] = len[j] + ;
cnt[i] = cnt[j];
}
}
if (mx == len[i]) res += cnt[i];
else if (mx < len[i]) {
mx = len[i];
res = cnt[i];
}
}
return res;
}
};

下面这种方法跟上面的解法基本一样,就是把更新结果 res 放在了遍历完数组之后,我们利用 mx 来找到所有的 cnt[i],累加到结果 res 上,参见代码如下:

解法二:

class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int res = , mx = , n = nums.size();
vector<int> len(n, ), cnt(n, );
for (int i = ; i < n; ++i) {
for (int j = ; j < i; ++j) {
if (nums[i] <= nums[j]) continue;
if (len[i] == len[j] + ) cnt[i] += cnt[j];
else if (len[i] < len[j] + ) {
len[i] = len[j] + ;
cnt[i] = cnt[j];
}
}
mx = max(mx, len[i]);
}
for (int i = ; i < n; ++i) {
if (mx == len[i]) res += cnt[i];
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/673

类似题目:

Longest Increasing Subsequence

Longest Continuous Increasing Subsequence

参考资料:

https://leetcode.com/problems/number-of-longest-increasing-subsequence/

https://leetcode.com/problems/number-of-longest-increasing-subsequence/discuss/107318/C%2B%2B-DP-with-explanation-O(n2)

https://leetcode.com/problems/number-of-longest-increasing-subsequence/discuss/107293/JavaC%2B%2B-Simple-dp-solution-with-explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Number of Longest Increasing Subsequence 最长递增序列的个数的更多相关文章

  1. [LeetCode] 673. Number of Longest Increasing Subsequence 最长递增序列的个数

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  2. 673. Number of Longest Increasing Subsequence最长递增子序列的数量

    [抄题]: Given an unsorted array of integers, find the number of longest increasing subsequence. Exampl ...

  3. leetcode300. Longest Increasing Subsequence 最长递增子序列 、674. Longest Continuous Increasing Subsequence

    Longest Increasing Subsequence 最长递增子序列 子序列不是数组中连续的数. dp表达的意思是以i结尾的最长子序列,而不是前i个数字的最长子序列. 初始化是dp所有的都为1 ...

  4. [LeetCode] Longest Increasing Subsequence 最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  5. [LeetCode] 300. Longest Increasing Subsequence 最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...

  6. LeetCode Number of Longest Increasing Subsequence

    原题链接在这里:https://leetcode.com/problems/number-of-longest-increasing-subsequence/description/ 题目: Give ...

  7. [leetcode]300. Longest Increasing Subsequence最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...

  8. [LintCode] Longest Increasing Subsequence 最长递增子序列

    Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return ...

  9. POJ 2533 Longest Ordered Subsequence 最长递增序列

      Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequenc ...

随机推荐

  1. vue/axios请求拦截

    import axios from 'axios';import { Message } from 'element-ui';import Cookies from 'js-cookie';impor ...

  2. 【Spring源码深度解析学习系列】默认标签解析(三)

    Spring的标签包括默认标签和自定义标签两种 默认标签的解析方法: ###DefaultBeanDefinitionDocumentReader.java### private void parse ...

  3. Active MQ 实战(一)

    1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...

  4. MySQL之集合函数与分组查询

    这是分组查询用到的语句,也包括了排序以及常用的集合函数

  5. 20155306 2017-2018-1《信息安全系统设计》第二周课堂测试以及myod的实现

    20155306 2017-2018-1<信息安全系统设计>第二周课堂测试以及myod的实现 第二周课堂测验: (注:前两项在课堂已提交,在此不做详解) 第一项: 每个.c一个文件,每个. ...

  6. C语言--第二周作业

    ****学习内容总结**** 1.Git和编辑器截图 2.MOOC截图 3.阅读<提问的智慧>感想 读完<提问的智慧>之后,我认为在提问时,要根据以下步骤: 谨慎明确的描述症状 ...

  7. servlet线程同步问题-代码实现同步(转)

    从servlet的生命周期中,我们知道,当第一次访问某个servlet后,该servlet的实例就会常驻 内存,以后再次访问该servlet就会访问同一个servlet实例,这样就带来多个用户去访问一 ...

  8. SpaceVim - 让你的vim变得更加高效和强大

    SpaceVim 中文手册 项 目 主 页: https://spacevim.org Github 地址 : https://github.com/SpaceVim/SpaceVim SpaceVi ...

  9. vue-router 组件实例被复用问题

    最近在开发过程中遇到如下问题: 当前路由是这样的 http://127.0.0.1:3010/order?keywords=22 只改变keywords的值,路由不跳转 http://127.0.0. ...

  10. js前端对后台数据的获取,如果是汉字则需要添上引号

    js前端对后台数据的获取,如果是汉字则需要添上引号