Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/673.html
673. Number of Longest Increasing Subsequence (Medium)
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.
Related Topics:
Dynamic Programming
Similar Questions:
Solution 1. DP
Consider the subproblem in range A[0..i]
and the LIS must ends with A[i]
.
Let len[i]
be the length of longest LIS ending with A[i]
.
Let cnt[i]
be the count of longest LIS ending with A[i]
.
len[i] = 1 + max( len[j] | 0 <= j < i && A[j] < A[i] )
cnt[i] = sum( cnt[j] | 0 <= j < i && len[j] + 1 == len[i] )
The answer is
sum( cnt[i] | len[i] == maxLen )
where maxLen = max( len[i] | 0 <= i < N )
// OJ: https://leetcode.com/problems/number-of-longest-increasing-subsequence/
// Time: O(N^2)
// Space: O(N)
class Solution {
public:
int findNumberOfLIS(vector<int>& A) {
if (A.empty()) return 0;
int N = A.size(), ans = 0, maxLen = 0;
vector<int> len(N, 1), cnt(N, 1);
for (int i = 0; i < N; ++i) {
for (int j = 0; j < i; ++j) {
if (A[j] >= A[i]) continue;
if (len[i] < 1 + len[j]) len[i] = 1 + len[j], cnt[i] = cnt[j];
else if (len[i] == 1 + len[j]) cnt[i] += cnt[j];
}
if (len[i] > maxLen) maxLen = len[i], ans = cnt[i];
else if (len[i] == maxLen) ans += cnt[i];
}
return ans;
}
};
Java
-
class Solution { public int findNumberOfLIS(int[] nums) { if (nums == null || nums.length == 0) return 0; if (nums.length == 1) return 1; int maxLength = 1; int length = nums.length; int[] dp = new int[length]; dp[0] = 1; for (int i = 1; i < length; i++) { dp[i] = 1; for (int j = 0; j < i; j++) { if (nums[j] < nums[i]) dp[i] = Math.max(dp[i], dp[j] + 1); } maxLength = Math.max(maxLength, dp[i]); } int[][] dp2d = new int[length][maxLength + 1]; for (int i = 0; i < length; i++) dp2d[i][0] = 1; dp2d[0][1] = 1; for (int i = 1; i < length; i++) { dp2d[i][1] = 1; for (int j = 0; j < i; j++) { if (nums[j] < nums[i]) { for (int k = 1; k < maxLength; k++) dp2d[i][k + 1] += dp2d[j][k]; } } } int count = 0; for (int i = 0; i < length; i++) count += dp2d[i][maxLength]; return count; } }
-
// OJ: https://leetcode.com/problems/number-of-longest-increasing-subsequence/ // Time: O(N^2) // Space: O(N) class Solution { public: int findNumberOfLIS(vector<int>& A) { if (A.empty()) return 0; int N = A.size(), ans = 0, maxLen = 0; vector<int> len(N, 1), cnt(N, 1); for (int i = 0; i < N; ++i) { for (int j = 0; j < i; ++j) { if (A[j] >= A[i]) continue; if (len[i] < 1 + len[j]) len[i] = 1 + len[j], cnt[i] = cnt[j]; else if (len[i] == 1 + len[j]) cnt[i] += cnt[j]; } if (len[i] > maxLen) maxLen = len[i], ans = cnt[i]; else if (len[i] == maxLen) ans += cnt[i]; } return ans; } };
-
class Solution: def findNumberOfLIS(self, nums: List[int]) -> int: maxLen, ans, n = 0, 0, len(nums) dp, cnt = [1] * n, [1] * n for i in range(n): for j in range(i): if nums[i] > nums[j]: if dp[j] + 1 > dp[i]: dp[i] = dp[j] + 1 cnt[i] = cnt[j] elif dp[j] + 1 == dp[i]: cnt[i] += cnt[j] if dp[i] > maxLen: maxLen = dp[i] ans = cnt[i] elif dp[i] == maxLen: ans += cnt[i] return ans ############ class Solution(object): def findNumberOfLIS(self, nums): """ :type nums: List[int] :rtype: int """ dp, longest = [[1, 1] for _ in range(len(nums))], 1 for i in range(1, len(nums)): curr_longest, count = 1, 0 for j in range(i): if nums[j] < nums[i]: curr_longest = max(curr_longest, dp[j][0] + 1) for j in range(i): if dp[j][0] == curr_longest - 1 and nums[j] < nums[i]: count += dp[j][1] dp[i] = [curr_longest, max(count, dp[i][1])] longest = max(longest, curr_longest) return sum([item[1] for item in dp if item[0] == longest])