JavaScript Program to Find the Longest Bitonic Subsequence | DP-15


We will be finding the longest bitonic subsequence in each array using dynamic programming. A bitonic subsequence is a sequence which is first increasing, then decreasing. To find the longest bitonic subsequence, we will use a two-step approach. First, we will find the longest increasing subsequence in the given array, then we will find the longest decreasing subsequence in the reverse of the given array. Finally, we will add the lengths of both the subsequences and subtract 1 to exclude the common element in the middle.

Approach

A bitonic sequence is a sequence that first increases and then decreases. The approach to finding the longest bitonic subsequence in a given array is to use dynamic programming.

  • Initialize two arrays, "inc" and "dec", to store the length of the longest increasing subsequence ending at each index.

  • Loop through the array, updating the values of "inc" and "dec" at each index using the values at previous indices.

  • Find the maximum value of the sum of "inc" and "dec" minus one at each index, as this will give the length of the longest bitonic subsequence that includes that index.

  • Return the maximum value found in step 3 as the length of the longest bitonic subsequence.

  • To reconstruct the longest bitonic subsequence, use the values in "inc" and "dec" to backtrack from the index that gives the maximum value in step 3.

  • Return the reconstructed sequence as the longest bitonic subsequence.

Example

Here is a complete working example of a JavaScript program to find the longest bitonic subsequence using dynamic programming −

function LBSLength(arr) {
   let n = arr.length;
   let lis = new Array(n).fill(1);
   let lds = new Array(n).fill(1);
     
   for (let i = 1; i < n; i++) {
      for (let j = 0; j < i; j++) {
         if (arr[i] > arr[j]) {
            lis[i] = Math.max(lis[i], lis[j] + 1);
         }
      }
   }
     
   for (let i = n - 2; i >= 0; i--) {
      for (let j = n - 1; j > i; j--) {
         if (arr[i] > arr[j]) {
            lds[i] = Math.max(lds[i], lds[j] + 1);
         }
      }
   }
     
   let maxLength = 0;
   for (let i = 0; i < n; i++) {
      maxLength = Math.max(maxLength, lis[i] + lds[i] - 1);
   }
    
   return maxLength;
}

const arr = [1, 7, 8, 11, 5, 2, 3];
console.log(LBSLength(arr)); 

Explanation

  • The first step is to initialize two arrays, lis and lds, with the same length as the input array arr and filled with 1's. lis stands for "longest increasing subsequence" and lds stands for "longest decreasing subsequence".

  • The next step is to calculate lis[i], the length of the longest increasing subsequence ending at arr[i]. This is done using a nested loop where j ranges from 0 to i-1. If arr[i] > arr[j], we update lis[i] to be the maximum of its current value and lis[j] + 1.

  • The next step is to calculate lds[i], the length of the longest decreasing subsequence starting at arr[i]. This is done using a nested loop where j ranges from n-1 to i+1. If arr[i] > arr[j], we update lds[i] to be the maximum of its current value and lds[j] + 1.

  • Finally, we loop through the n elements of the input array and find the maximum value of lis[i] + lds[i] - 1, which represents the length of the longest bitonic subsequence ending and starting at arr[i]. This value is stored in the variable maxLength.

  • The function returns maxLength, which is the length of the longest bitonic subsequence in the input array.

Updated on: 15-Mar-2023

121 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements