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)

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.

[ad type=”banner”]

Following is Java implementation of the above Dynamic Programming solution.

[pastacode lang=”java” manual=”%2F*%20Dynamic%20Programming%20implementation%20in%20Java%20for%20longest%20bitonic%0A%20%20%20subsequence%20problem%20*%2F%0Aimport%20java.util.*%3B%0Aimport%20java.lang.*%3B%0Aimport%20java.io.*%3B%0A%20%0Aclass%20LBS%0A%7B%0A%20%20%20%20%2F*%20lbs()%20returns%20the%20length%20of%20the%20Longest%20Bitonic%20Subsequence%20in%0A%20%20%20%20arr%5B%5D%20of%20size%20n.%20The%20function%20mainly%20creates%20two%20temporary%20arrays%0A%20%20%20%20lis%5B%5D%20and%20lds%5B%5D%20and%20returns%20the%20maximum%20lis%5Bi%5D%20%2B%20lds%5Bi%5D%20-%201.%0A%20%0A%20%20%20%20lis%5Bi%5D%20%3D%3D%3E%20Longest%20Increasing%20subsequence%20ending%20with%20arr%5Bi%5D%0A%20%20%20%20lds%5Bi%5D%20%3D%3D%3E%20Longest%20decreasing%20subsequence%20starting%20with%20arr%5Bi%5D%0A%20%20%20%20*%2F%0A%20%20%20%20static%20int%20lbs(%20int%20arr%5B%5D%2C%20int%20n%20)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20int%20i%2C%20j%3B%0A%20%0A%20%20%20%20%20%20%20%20%2F*%20Allocate%20memory%20for%20LIS%5B%5D%20and%20initialize%20LIS%20values%20as%201%20for%0A%20%20%20%20%20%20%20%20%20%20%20%20all%20indexes%20*%2F%0A%20%20%20%20%20%20%20%20int%5B%5D%20lis%20%3D%20new%20int%5Bn%5D%3B%0A%20%20%20%20%20%20%20%20for%20(i%20%3D%200%3B%20i%20%3C%20n%3B%20i%2B%2B)%0A%20%20%20%20%20%20%20%20%20%20%20%20lis%5Bi%5D%20%3D%201%3B%0A%20%0A%20%20%20%20%20%20%20%20%2F*%20Compute%20LIS%20values%20from%20left%20to%20right%20*%2F%0A%20%20%20%20%20%20%20%20for%20(i%20%3D%201%3B%20i%20%3C%20n%3B%20i%2B%2B)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(j%20%3D%200%3B%20j%20%3C%20i%3B%20j%2B%2B)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(arr%5Bi%5D%20%3E%20arr%5Bj%5D%20%26%26%20lis%5Bi%5D%20%3C%20lis%5Bj%5D%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lis%5Bi%5D%20%3D%20lis%5Bj%5D%20%2B%201%3B%0A%20%0A%20%20%20%20%20%20%20%20%2F*%20Allocate%20memory%20for%20lds%20and%20initialize%20LDS%20values%20for%0A%20%20%20%20%20%20%20%20%20%20%20%20all%20indexes%20*%2F%0A%20%20%20%20%20%20%20%20int%5B%5D%20lds%20%3D%20new%20int%20%5Bn%5D%3B%0A%20%20%20%20%20%20%20%20for%20(i%20%3D%200%3B%20i%20%3C%20n%3B%20i%2B%2B)%0A%20%20%20%20%20%20%20%20%20%20%20%20lds%5Bi%5D%20%3D%201%3B%0A%20%0A%20%20%20%20%20%20%20%20%2F*%20Compute%20LDS%20values%20from%20right%20to%20left%20*%2F%0A%20%20%20%20%20%20%20%20for%20(i%20%3D%20n-2%3B%20i%20%3E%3D%200%3B%20i–)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(j%20%3D%20n-1%3B%20j%20%3E%20i%3B%20j–)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(arr%5Bi%5D%20%3E%20arr%5Bj%5D%20%26%26%20lds%5Bi%5D%20%3C%20lds%5Bj%5D%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lds%5Bi%5D%20%3D%20lds%5Bj%5D%20%2B%201%3B%0A%20%0A%20%0A%20%20%20%20%20%20%20%20%2F*%20Return%20the%20maximum%20value%20of%20lis%5Bi%5D%20%2B%20lds%5Bi%5D%20-%201*%2F%0A%20%20%20%20%20%20%20%20int%20max%20%3D%20lis%5B0%5D%20%2B%20lds%5B0%5D%20-%201%3B%0A%20%20%20%20%20%20%20%20for%20(i%20%3D%201%3B%20i%20%3C%20n%3B%20i%2B%2B)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(lis%5Bi%5D%20%2B%20lds%5Bi%5D%20-%201%20%3E%20max)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20max%20%3D%20lis%5Bi%5D%20%2B%20lds%5Bi%5D%20-%201%3B%0A%20%0A%20%20%20%20%20%20%20%20return%20max%3B%0A%20%20%20%20%7D%0A%20%0A%20%20%20%20public%20static%20void%20main%20(String%5B%5D%20args)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20int%20arr%5B%5D%20%3D%20%7B0%2C%208%2C%204%2C%2012%2C%202%2C%2010%2C%206%2C%2014%2C%201%2C%209%2C%205%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2013%2C%203%2C%2011%2C%207%2C%2015%7D%3B%0A%20%20%20%20%20%20%20%20int%20n%20%3D%20arr.length%3B%0A%20%20%20%20%20%20%20%20System.out.println(%22Length%20of%20LBS%20is%20%22%2B%20lbs(%20arr%2C%20n%20))%3B%0A%20%20%20%20%7D%0A%7D” message=”Java” highlight=”” provider=”manual”/]

Output :

 Length of LBS is 7

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

[ad type=”banner”]