赞
踩
给定一个未排序的整数数组,找到最长递增子序列的个数。
示例 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。
解题思路:
首先,最长子序列的长度我们可以用动态规划的思想来解决
定义dp数组为以nums[i]为结尾的子序列的最大长度
因此我们有以下转移方程
if(nums[i]>nums[j])
dp[i] = Math.max(dp[i], dp[j]+1)
这一转移方程的含义就是,我要么就保持当前序列的长度,要么放弃当前序列的前面的数字,将当前数字加到以nums[j]结尾的子序列上去
另外,这道题要我们找到长度最大的子序列的个数,也就是说,我们不仅要找到最大子序列的长度,还要找到该长度的所有子序列的个数
我们可以用一个count数组来解决这个问题,我们考虑以下转移方程
1,3,5,4,7
长度为3的子序列有1,3,5
和1,3,4
, 所以长度为4的子序列的count应该就是这两个的count之和代码如下:
class Solution { public int findNumberOfLIS(int[] nums) { int N = nums.length; if (N <= 1) return N; int[] lengths = new int[N]; int[] counts = new int[N]; Arrays.fill(counts, 1); for (int j = 0; j < N; ++j) { for (int i = 0; i < j; ++i) if (nums[i] < nums[j]) { if (lengths[i] >= lengths[j]) { lengths[j] = lengths[i] + 1; counts[j] = counts[i]; } else if (lengths[i] + 1 == lengths[j]) { counts[j] += counts[i]; } } } int longest = 0, ans = 0; for (int length: lengths) { longest = Math.max(longest, length); } for (int i = 0; i < N; ++i) { if (lengths[i] == longest) { ans += counts[i]; } } return ans; } }
时间复杂度为O(N^2)
空间复杂度为O(N)
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。