给定大小为N的数组arr [] ,任务是计算给定数组中存在的最长递增子序列的数量。
例子:
Input: arr[] = {2, 2, 2, 2, 2}
Output: 5
Explanation: The length of the longest increasing subsequence is 1, i.e. {2}. Therefore, count of longest increasing subsequences of length 1 is 5.
Input: arr[] = {1, 3, 5, 4, 7}
Output: 2
Explanation: The length of the longest increasing subsequence is 4, and there are 2 longest increasing subsequences of length 4, i.e. {1, 3, 4, 7} and {1, 3, 5, 7}.
天真的方法:最简单的方法是生成给定数组arr []中存在的所有可能的子序列,并计算最大长度的递增子序列。检查所有子序列后打印计数。
时间复杂度: O(N * 2 N )
辅助空间: O(1)
高效方法:为了优化上述方法,其想法是使用动态编程,因为上述问题具有需要多次计算的重叠子问题,并使用制表或备忘录来减少该计算。请按照以下步骤解决问题:
- 初始化两个数组dp_l []和dp_c []分别存储每个索引处最长增长子序列的长度和最长增长子序列的计数。
- 使用变量i遍历[1,N – 1]范围:
- 使用变量j在[0,i – 1]范围内迭代:
- 如果arr [i]> arr [j],请检查以下情况:
〜如果( dp_l [j] +1)大于dp_l [i] ,则将dp_l [i]更新为dp_l [j] +1 ,将dp_c [i]更新为dp_c [j]
〜否则如果(dp_l [J] + 1)是一样的dp_l [I],然后更新dp_c [I]作为dp_c [I] + dp_c [J]。
- 如果arr [i]> arr [j],请检查以下情况:
- 使用变量j在[0,i – 1]范围内迭代:
- 在数组dp_l []中找到最大元素,并将其存储在变量max_length中,该变量将给出LIS的长度。
- 用0初始化变量计数,以存储最长的递增子序列数。
- 遍历数组dp_l [] ,如果在任何索引idx处, dp_l [idx]与max_length相同,则将计数增加dp_c [idx] 。
- 完成上述步骤后,打印count的值,它是给定数组中最长的递增子序列数。
下面是上述方法的实现:
C++
// C++ program for the
// above approach
#include
using namespace std;
//Function to count the number
// of LIS in the array nums[]
int findNumberOfLIS(vector nums)
{
//Base Case
if (nums.size() == 0)
return 0;
int n = nums.size();
//Initialize dp_l array with
// 1s
vector dp_l(n, 1);
//Initialize dp_c array with
// 1s
vector dp_c(n, 1);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i; j++)
{
//If current element is
// smaller
if (nums[i] <= nums[j])
continue;
if (dp_l[j] + 1 > dp_l[i])
{
dp_l[i] = dp_l[j] + 1;
dp_c[i] = dp_c[j];
}
else if (dp_l[j] + 1 == dp_l[i])
dp_c[i] += dp_c[j];
}
}
//Store the maximum element
// from dp_l
int max_length = 0;
for (int i : dp_l)
max_length = max(i,max_length);
//Stores the count of LIS
int count = 0;
//Traverse dp_l and dp_c
// simultaneously
for(int i = 0; i < n; i++)
{
//Update the count
if (dp_l[i] == max_length)
count += dp_c[i];
}
//Return the count of LIS
return count;
}
//Driver code
int main()
{
//Given array arr[]
vector arr = {1, 3, 5, 4, 7};
//Function Call
cout << findNumberOfLIS(arr) << endl;
}
// This code is contributed by Mohit Kumar 29
Java
// Java program for the
// above approach
import java.util.*;
class GFG{
// Function to count the number
// of LIS in the array nums[]
static int findNumberOfLIS(int[] nums)
{
// Base Case
if (nums.length == 0)
return 0;
int n = nums.length;
// Initialize dp_l array with
// 1s
int[] dp_l = new int[n];
Arrays.fill(dp_l, 1);
// Initialize dp_c array with
// 1s
int[] dp_c = new int[n];
Arrays.fill(dp_c, 1);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < i; j++)
{
// If current element is
// smaller
if (nums[i] <= nums[j])
continue;
if (dp_l[j] + 1 > dp_l[i])
{
dp_l[i] = dp_l[j] + 1;
dp_c[i] = dp_c[j];
}
else if (dp_l[j] + 1 == dp_l[i])
dp_c[i] += dp_c[j];
}
}
// Store the maximum element
// from dp_l
int max_length = 0;
for(int i : dp_l)
max_length = Math.max(i, max_length);
// Stores the count of LIS
int count = 0;
// Traverse dp_l and dp_c
// simultaneously
for(int i = 0; i < n; i++)
{
// Update the count
if (dp_l[i] == max_length)
count += dp_c[i];
}
// Return the count of LIS
return count;
}
// Driver code
public static void main(String[] args)
{
// Given array arr[]
int[] arr = { 1, 3, 5, 4, 7 };
// Function Call
System.out.print(findNumberOfLIS(arr) + "\n");
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
# Function to count the number of LIS
# in the array nums[]
def findNumberOfLIS(nums):
# Base Case
if not nums:
return 0
n = len(nums)
# Initialize dp_l array with 1s
dp_l = [1] * n
# Initialize dp_c array with 1s
dp_c = [1] * n
for i, num in enumerate(nums):
for j in range(i):
# If current element is smaller
if nums[i] <= nums[j]:
continue
# Otherwise
if dp_l[j] + 1 > dp_l[i]:
dp_l[i] = dp_l[j] + 1
dp_c[i] = dp_c[j]
elif dp_l[j] + 1 == dp_l[i]:
dp_c[i] += dp_c[j]
# Store the maximum element from dp_l
max_length = max(x for x in dp_l)
# Stores the count of LIS
count = 0
# Traverse dp_l and dp_c simultaneously
for l, c in zip(dp_l, dp_c):
# Update the count
if l == max_length:
count += c
# Return the count of LIS
return count
# Driver Code
# Given array arr[]
arr = [1, 3, 5, 4, 7]
# Function Call
print(findNumberOfLIS(arr))
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to count the number
// of LIS in the array nums[]
static int findNumberOfLIS(int[] nums)
{
// Base Case
if (nums.Length == 0)
return 0;
int n = nums.Length;
// Initialize dp_l array with
// 1s
int[] dp_l = new int[n];
Array.Fill(dp_l, 1);
// Initialize dp_c array with
// 1s
int[] dp_c = new int[n];
Array.Fill(dp_c, 1);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < i; j++)
{
// If current element is
// smaller
if (nums[i] <= nums[j])
continue;
if (dp_l[j] + 1 > dp_l[i])
{
dp_l[i] = dp_l[j] + 1;
dp_c[i] = dp_c[j];
}
else if (dp_l[j] + 1 == dp_l[i])
dp_c[i] += dp_c[j];
}
}
// Store the maximum element
// from dp_l
int max_length = 0;
foreach(int i in dp_l)
max_length = Math.Max(i, max_length);
// Stores the count of LIS
int count = 0;
// Traverse dp_l and dp_c
// simultaneously
for(int i = 0; i < n; i++)
{
// Update the count
if (dp_l[i] == max_length)
count += dp_c[i];
}
// Return the count of LIS
return count;
}
// Driver code
static void Main() {
// Given array arr[]
int[] arr = { 1, 3, 5, 4, 7 };
// Function Call
Console.WriteLine(findNumberOfLIS(arr));
}
}
// This code is contributed by divyeshrabadiya07
2
时间复杂度: O(N 2 )
辅助空间: O(N)