给定一个大小为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 初始化一个变量count来存储最长递增子序列的数量。
- 遍历数组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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live