Related Articles
Longest Bitonic Subsequence | DP-15
• Difficulty Level : Medium
• Last Updated : 24 Mar, 2021

Given an array arr[0 … n-1] containing n positive integers, a subsequence of arr[] is called Bitonic if it is first increasing, then decreasing. Write a function that takes an array as argument and returns the length of the longest bitonic subsequence.
A sequence, sorted in increasing order is considered Bitonic with the decreasing part as empty. Similarly, decreasing order sequence is considered Bitonic with the increasing part as empty.
Examples:

```Input arr[] = {1, 11, 2, 10, 4, 5, 2, 1};
Output: 6 (A Longest Bitonic Subsequence of length 6 is 1, 2, 10, 4, 2, 1)

Input arr[] = {12, 11, 40, 5, 3, 1}
Output: 5 (A Longest Bitonic Subsequence of length 5 is 12, 11, 5, 3, 1)

Input arr[] = {80, 60, 30, 40, 20, 10}
Output: 5 (A Longest Bitonic Subsequence of length 5 is 80, 60, 30, 20, 10)```

Source: Microsoft Interview Question

Solution
This problem is a variation of standard Longest Increasing Subsequence (LIS) problem. Let the input array be arr[] of length n. We need to construct two arrays lis[] and lds[] using Dynamic Programming solution of LIS problem. lis[i] stores the length of the Longest Increasing subsequence ending with arr[i]. lds[i] stores the length of the longest Decreasing subsequence starting from arr[i]. Finally, we need to return the max value of lis[i] + lds[i] – 1 where i is from 0 to n-1.
Following is the implementation of the above Dynamic Programming solution.

## C++

 `/* Dynamic Programming implementation of longest bitonic subsequence problem */``#include``#include` `/* lbs() returns the length of the Longest Bitonic Subsequence in``    ``arr[] of size n. The function mainly creates two temporary arrays``    ``lis[] and lds[] and returns the maximum lis[i] + lds[i] - 1.` `    ``lis[i] ==> Longest Increasing subsequence ending with arr[i]``    ``lds[i] ==> Longest decreasing subsequence starting with arr[i]``*/``int` `lbs( ``int` `arr[], ``int` `n )``{``   ``int` `i, j;` `   ``/* Allocate memory for LIS[] and initialize LIS values as 1 for``      ``all indexes */``   ``int` `*lis = ``new` `int``[n];``   ``for` `(i = 0; i < n; i++)``      ``lis[i] = 1;` `   ``/* Compute LIS values from left to right */``   ``for` `(i = 1; i < n; i++)``      ``for` `(j = 0; j < i; j++)``         ``if` `(arr[i] > arr[j] && lis[i] < lis[j] + 1)``            ``lis[i] = lis[j] + 1;` `   ``/* Allocate memory for lds and initialize LDS values for``      ``all indexes */``   ``int` `*lds = ``new` `int` `[n];``   ``for` `(i = 0; i < n; i++)``      ``lds[i] = 1;` `   ``/* Compute LDS values from right to left */``   ``for` `(i = n-2; i >= 0; i--)``      ``for` `(j = n-1; j > i; j--)``         ``if` `(arr[i] > arr[j] && lds[i] < lds[j] + 1)``            ``lds[i] = lds[j] + 1;`  `   ``/* Return the maximum value of lis[i] + lds[i] - 1*/``   ``int` `max = lis + lds - 1;``   ``for` `(i = 1; i < n; i++)``     ``if` `(lis[i] + lds[i] - 1 > max)``         ``max = lis[i] + lds[i] - 1;``   ``return` `max;``}` `/* Driver program to test above function */``int` `main()``{``  ``int` `arr[] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5,``              ``13, 3, 11, 7, 15};``  ``int` `n = ``sizeof``(arr)/``sizeof``(arr);``  ``printf``(``"Length of LBS is %d\n"``, lbs( arr, n ) );``  ``return` `0;``}`

## Java

 `/* Dynamic Programming implementation in Java for longest bitonic``   ``subsequence problem */``import` `java.util.*;``import` `java.lang.*;``import` `java.io.*;` `class` `LBS``{``    ``/* lbs() returns the length of the Longest Bitonic Subsequence in``    ``arr[] of size n. The function mainly creates two temporary arrays``    ``lis[] and lds[] and returns the maximum lis[i] + lds[i] - 1.` `    ``lis[i] ==> Longest Increasing subsequence ending with arr[i]``    ``lds[i] ==> Longest decreasing subsequence starting with arr[i]``    ``*/``    ``static` `int` `lbs( ``int` `arr[], ``int` `n )``    ``{``        ``int` `i, j;` `        ``/* Allocate memory for LIS[] and initialize LIS values as 1 for``            ``all indexes */``        ``int``[] lis = ``new` `int``[n];``        ``for` `(i = ``0``; i < n; i++)``            ``lis[i] = ``1``;` `        ``/* Compute LIS values from left to right */``        ``for` `(i = ``1``; i < n; i++)``            ``for` `(j = ``0``; j < i; j++)``                ``if` `(arr[i] > arr[j] && lis[i] < lis[j] + ``1``)``                    ``lis[i] = lis[j] + ``1``;` `        ``/* Allocate memory for lds and initialize LDS values for``            ``all indexes */``        ``int``[] lds = ``new` `int` `[n];``        ``for` `(i = ``0``; i < n; i++)``            ``lds[i] = ``1``;` `        ``/* Compute LDS values from right to left */``        ``for` `(i = n-``2``; i >= ``0``; i--)``            ``for` `(j = n-``1``; j > i; j--)``                ``if` `(arr[i] > arr[j] && lds[i] < lds[j] + ``1``)``                    ``lds[i] = lds[j] + ``1``;`  `        ``/* Return the maximum value of lis[i] + lds[i] - 1*/``        ``int` `max = lis[``0``] + lds[``0``] - ``1``;``        ``for` `(i = ``1``; i < n; i++)``            ``if` `(lis[i] + lds[i] - ``1` `> max)``                ``max = lis[i] + lds[i] - ``1``;` `        ``return` `max;``    ``}` `    ``public` `static` `void` `main (String[] args)``    ``{``        ``int` `arr[] = {``0``, ``8``, ``4``, ``12``, ``2``, ``10``, ``6``, ``14``, ``1``, ``9``, ``5``,``                    ``13``, ``3``, ``11``, ``7``, ``15``};``        ``int` `n = arr.length;``        ``System.out.println(``"Length of LBS is "``+ lbs( arr, n ));``    ``}``}`

## Python

 `# Dynamic Programming implementation of longest bitonic subsequence problem``"""``lbs() returns the length of the Longest Bitonic Subsequence in``arr[] of size n. The function mainly creates two temporary arrays``lis[] and lds[] and returns the maximum lis[i] + lds[i] - 1.` `lis[i] ==> Longest Increasing subsequence ending with arr[i]``lds[i] ==> Longest decreasing subsequence starting with arr[i]``"""` `def` `lbs(arr):``    ``n ``=` `len``(arr)`  `    ``# allocate memory for LIS[] and initialize LIS values as 1``    ``# for all indexes``    ``lis ``=` `[``1` `for` `i ``in` `range``(n``+``1``)]` `    ``# Compute LIS values from left to right``    ``for` `i ``in` `range``(``1` `, n):``        ``for` `j ``in` `range``(``0` `, i):``            ``if` `((arr[i] > arr[j]) ``and` `(lis[i] < lis[j] ``+``1``)):``                ``lis[i] ``=` `lis[j] ``+` `1` `    ``# allocate memory for LDS and initialize LDS values for``    ``# all indexes``    ``lds ``=` `[``1` `for` `i ``in` `range``(n``+``1``)]``    ` `    ``# Compute LDS values from right to left``    ``for` `i ``in` `reversed``(``range``(n``-``1``)): ``#loop from n-2 downto 0``        ``for` `j ``in` `reversed``(``range``(i``-``1` `,n)): ``#loop from n-1 downto i-1``            ``if``(arr[i] > arr[j] ``and` `lds[i] < lds[j] ``+` `1``):``                ``lds[i] ``=` `lds[j] ``+` `1`  `    ``# Return the maximum value of (lis[i] + lds[i] - 1)``    ``maximum ``=` `lis[``0``] ``+` `lds[``0``] ``-` `1``    ``for` `i ``in` `range``(``1` `, n):``        ``maximum ``=` `max``((lis[i] ``+` `lds[i]``-``1``), maximum)``    ` `    ``return` `maximum` `# Driver program to test the above function``arr ``=`  `[``0` `, ``8` `, ``4``, ``12``, ``2``, ``10` `, ``6` `, ``14` `, ``1` `, ``9` `, ``5` `, ``13``,``        ``3``, ``11` `, ``7` `, ``15``]``print` `"Length of LBS is"``,lbs(arr)` `# This code is contributed by Nikhil Kumar Singh(nickzuck_007)`

## C#

 `/* Dynamic Programming implementation in``   ``C# for longest bitonic subsequence problem */``using` `System;` `class` `LBS {``    ` `    ``/* lbs() returns the length of the Longest Bitonic Subsequence in``    ``arr[] of size n. The function mainly creates two temporary arrays``    ``lis[] and lds[] and returns the maximum lis[i] + lds[i] - 1.` `    ``lis[i] ==> Longest Increasing subsequence ending with arr[i]``    ``lds[i] ==> Longest decreasing subsequence starting with arr[i]``    ``*/``    ``static` `int` `lbs(``int``[] arr, ``int` `n)``    ``{``        ``int` `i, j;` `        ``/* Allocate memory for LIS[] and initialize``           ``LIS values as 1 for all indexes */``        ``int``[] lis = ``new` `int``[n];``        ``for` `(i = 0; i < n; i++)``            ``lis[i] = 1;` `        ``/* Compute LIS values from left to right */``        ``for` `(i = 1; i < n; i++)``            ``for` `(j = 0; j < i; j++)``                ``if` `(arr[i] > arr[j] && lis[i] < lis[j] + 1)``                    ``lis[i] = lis[j] + 1;` `        ``/* Allocate memory for lds and initialize LDS values for``            ``all indexes */``        ``int``[] lds = ``new` `int``[n];``        ``for` `(i = 0; i < n; i++)``            ``lds[i] = 1;` `        ``/* Compute LDS values from right to left */``        ``for` `(i = n - 2; i >= 0; i--)``            ``for` `(j = n - 1; j > i; j--)``                ``if` `(arr[i] > arr[j] && lds[i] < lds[j] + 1)``                    ``lds[i] = lds[j] + 1;` `        ``/* Return the maximum value of lis[i] + lds[i] - 1*/``        ``int` `max = lis + lds - 1;``        ``for` `(i = 1; i < n; i++)``            ``if` `(lis[i] + lds[i] - 1 > max)``                ``max = lis[i] + lds[i] - 1;` `        ``return` `max;``    ``}``    ` `    ``// Driver code``    ``public` `static` `void` `Main()``    ``{``        ``int``[] arr = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5,``                                      ``13, 3, 11, 7, 15 };``        ``int` `n = arr.Length;``        ``Console.WriteLine(``"Length of LBS is "` `+ lbs(arr, n));``    ``}``}` `// This code is contributed by vt_m.`

## PHP

 ` Longest Increasing subsequence``              ``ending with arr[i]``   ``lds[i] ==> Longest decreasing subsequence``              ``starting with arr[i]``*/``function` `lbs(&``\$arr``, ``\$n``)``{` `    ``/* Allocate memory for LIS[] and initialize``       ``LIS values as 1 for all indexes */``    ``\$lis` `= ``array_fill``(0, ``\$n``, NULL);``    ``for` `(``\$i` `= 0; ``\$i` `< ``\$n``; ``\$i``++)``        ``\$lis``[``\$i``] = 1;``    ` `    ``/* Compute LIS values from left to right */``    ``for` `(``\$i` `= 1; ``\$i` `< ``\$n``; ``\$i``++)``        ``for` `(``\$j` `= 0; ``\$j` `< ``\$i``; ``\$j``++)``            ``if` `(``\$arr``[``\$i``] > ``\$arr``[``\$j``] &&``                ``\$lis``[``\$i``] < ``\$lis``[``\$j``] + 1)``                ``\$lis``[``\$i``] = ``\$lis``[``\$j``] + 1;``    ` `    ``/* Allocate memory for lds and initialize``       ``LDS values for all indexes */``    ``\$lds` `= ``array_fill``(0, ``\$n``, NULL);``    ``for` `(``\$i` `= 0; ``\$i` `< ``\$n``; ``\$i``++)``        ``\$lds``[``\$i``] = 1;``    ` `    ``/* Compute LDS values from right to left */``    ``for` `(``\$i` `= ``\$n` `- 2; ``\$i` `>= 0; ``\$i``--)``        ``for` `(``\$j` `= ``\$n` `- 1; ``\$j` `> ``\$i``; ``\$j``--)``            ``if` `(``\$arr``[``\$i``] > ``\$arr``[``\$j``] &&``                ``\$lds``[``\$i``] < ``\$lds``[``\$j``] + 1)``                ``\$lds``[``\$i``] = ``\$lds``[``\$j``] + 1;``    ` `    ``/* Return the maximum value of``       ``lis[i] + lds[i] - 1*/``    ``\$max` `= ``\$lis`` + ``\$lds`` - 1;``    ``for` `(``\$i` `= 1; ``\$i` `< ``\$n``; ``\$i``++)``        ``if` `(``\$lis``[``\$i``] + ``\$lds``[``\$i``] - 1 > ``\$max``)``            ``\$max` `= ``\$lis``[``\$i``] + ``\$lds``[``\$i``] - 1;``    ``return` `\$max``;``}` `// Driver Code``\$arr` `= ``array``(0, 8, 4, 12, 2, 10, 6, 14,``             ``1, 9, 5, 13, 3, 11, 7, 15);``\$n` `= sizeof(``\$arr``);``echo` `"Length of LBS is "` `. lbs( ``\$arr``, ``\$n` `);` `// This code is contributed by ita_c``?>`

## Javascript

 ``

Output:

` Length of LBS is 7`

Time Complexity: O(n^2)
Auxiliary Space: O(n)

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up