Number of Longest Increasing Subsequences

09 Jun, 2021
Given an array arr[] of size N, the task is to count the number of longest increasing subsequences present in the given array.
Examples:
Input: arr[] = {2, 2, 2, 2, 2}Output: 5Explanation: 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: 2Explanation: 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}.
Naive Approach: The simplest approach is to generate all possible subsequences present in the given array arr[] and count the increasing subsequences of maximum length. Print the count after checking all subsequences. 
Time Complexity: O(N*2N)Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to use Dynamic Programming as the above problem has overlapping subproblems that need to be calculated more than once, and to reduce that calculation use tabulation or memoization. Follow the steps below to solve the problem:
Initialize two arrays dp_l[] and dp_c[] to store the length of the longest increasing subsequences and the count of the longest increasing subsequence at each index respectively.
Iterate over the range [1, N – 1] using the variable i:Iterate over the range [0, i – 1] using the variable j:If arr[i] > arr[j] then check for the following cases:        ~ If (dp_l[j]+1) greater than dp_l[i], then update dp_l[i] as dp_l[j] + 1 and dp_c[i] as dp_c[j]        ~ Else if (dp_l[j] + 1) is the same as dp_l[i], then update dp_c[i] as dp_c[i] + dp_c[j].
Iterate over the range [0, i – 1] using the variable j:If arr[i] > arr[j] then check for the following cases:        ~ If (dp_l[j]+1) greater than dp_l[i], then update dp_l[i] as dp_l[j] + 1 and dp_c[i] as dp_c[j]        ~ Else if (dp_l[j] + 1) is the same as dp_l[i], then update dp_c[i] as dp_c[i] + dp_c[j].
If arr[i] > arr[j] then check for the following cases:        ~ If (dp_l[j]+1) greater than dp_l[i], then update dp_l[i] as dp_l[j] + 1 and dp_c[i] as dp_c[j]        ~ Else if (dp_l[j] + 1) is the same as dp_l[i], then update dp_c[i] as dp_c[i] + dp_c[j].
Find the maximum element in the array dp_l[] and store it in a variable max_length that will give the length of LIS.
Initialize a variable count with 0 to store the number of the longest increasing subsequence.
Traverse the array dp_l[] and if at any index idx, dp_l[idx] is the same as max_length then increment the count by dp_c[idx].
After the above steps, print the value of count, which is the number of longest increasing subsequences in the given array.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the// above approach#include <bits/stdc++.h>using namespace std; //Function to count the number// of LIS in the array nums[]int findNumberOfLIS(vector<int> nums){  //Base Case  if (nums.size() == 0)    return 0;   int n = nums.size();   //Initialize dp_l array with  // 1s  vector<int> dp_l(n, 1);   //Initialize dp_c array with  // 1s  vector<int> 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 codeint main(){  //Given array arr[]  vector<int> arr = {1, 3, 5, 4, 7};   //Function Call  cout << findNumberOfLIS(arr) << endl;} // This code is contributed by Mohit Kumar 29
// Java program for the// above approachimport 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 codepublic 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 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 Callprint(findNumberOfLIS(arr))
// C# program to implement// the above approachusing 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
<script> // Javascript program for the// above approach // Function to count the number// of LIS in the array nums[]function findNumberOfLIS(nums){  //Base Case  if (nums.length == 0)    return 0;   var n = nums.length;   // Initialize dp_l array with  // 1s  var dp_l = Array(n).fill(1);   // Initialize dp_c array with  // 1s  var dp_c = Array(n).fill(1);   for (var i = 0; i < n; i++)  {    for (var 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  var max_length = 0;   dp_l.forEach(i => {           max_length = Math.max(i,max_length);  });   // Stores the count of LIS  var count = 0;   //Traverse dp_l and dp_c  // simultaneously  for(var 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// Given array arr[]var arr = [1, 3, 5, 4, 7]; // Function Calldocument.write( findNumberOfLIS(arr)); // This code is contributed by rutvik_56.</script>
2
 
Time Complexity: O(N2)Auxiliary Space: O(N)
mohit kumar 29
shikhasingrajput
divyeshrabadiya07
tridib_samanta
rutvik_56
LIS
Memoization
subsequence
Arrays
Dynamic Programming
Recursion
Arrays
Dynamic Programming
Recursion
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Introduction to Arrays
Program for Fibonacci numbers
0-1 Knapsack Problem | DP-10
Longest Common Subsequence | DP-4
Subset Sum Problem | DP-25
Longest Palindromic Substring | Set 1