📜  最长递增子序列数

📅  最后修改于: 2021-05-17 16:38:28             🧑  作者: Mango

给定大小为N的数组arr [] ,任务是计算给定数组中存在的最长递增子序列的数量。

例子:

天真的方法:最简单的方法是生成给定数组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]。
  • 在数组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)