# Print Longest Bitonic subsequence (Space Optimized Approach)

Last Updated : 14 Jun, 2021

Given an array arr[] of size N, the task is to print the longest bitonic subsequence of the given array.
Note: If more than one solution exit then prints anyone solution.

Examples:

Input: arr[] = {1, 11, 2, 10, 4, 5, 2, 1}
Output: 1 11 10 5 2 1
Explanation:
All possible longest bitonic subsequences from the above array are {1, 2, 10, 4, 2, 1}, {1, 11, 10, 5, 2, 1}, {1, 2, 4, 5, 2, 1}.
Therefore, print any of them to obtain the answer.

Input: arr[] = {80, 60, 30, 40, 20, 10}
Output: 80 60 30 20 10

Dynamic Programming Approach using Extra Space: Refer to the previous article for the 2D Dynamic programming approach to solve the problem.
Time Complexity: O(N2
Auxiliary Space: O(N2)

Space-Optimized Approach: The auxiliary space used for the above approach can be optimized by using 1D Dynamic Programming. Follow the below steps to solve the problem.

1. Create two arrays lis[] and lds[] to store, at every ith Index, the length of the longest increasing and decreasing subsequences ending with the element arr[i] respectively.
2. Once computed, find the ith index which contains the maximum value of lis[i] + lds[i] – 1
3. Create res[] to store all the elements of the longest bitonic sequence in decreasing order of elements followed by increasing order of elements.
4. Print the res[] array.

Below is the implement the above approach:

## C++

 `// C++ Program to implement` `// the above approach`   `#include ` `using` `namespace` `std;`   `// Function to print the longest` `// bitonic subsequence` `void` `printRes(vector<``int``>& res)` `{` `    ``int` `n = res.size();` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``cout << res[i] << ``" "``;` `    ``}` `}`   `// Function to generate the longest` `// bitonic subsequence` `void` `printLBS(``int` `arr[], ``int` `N)` `{`   `    ``// Store the lengths of LIS` `    ``// ending at every index` `    ``int` `lis[N];`   `    ``// Store the lengths of LDS` `    ``// ending at every index` `    ``int` `lds[N];`   `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``lis[i] = lds[i] = 1;` `    ``}`   `    ``// Compute LIS for all indices` `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``for` `(``int` `j = 0; j < i; j++) {`   `            ``if` `(arr[j] < arr[i]) {`   `                ``if` `(lis[i] < lis[j] + 1)` `                    ``lis[i] = lis[j] + 1;` `            ``}` `        ``}` `    ``}`   `    ``// Compute LDS for all indices` `    ``for` `(``int` `i = N - 1; i >= 0; i--) {`   `        ``for` `(``int` `j = N - 1; j > i; j--) {` `            ``if` `(arr[j] < arr[i]) {`   `                ``if` `(lds[i] < lds[j] + 1)` `                    ``lds[i] = lds[j] + 1;` `            ``}` `        ``}` `    ``}`   `    ``// Find the index having` `    ``// maximum value of` `    ``// lis[i] + lds[i] - 1` `    ``int` `MaxVal = arr[0], inx = 0;` `    ``for` `(``int` `i = 0; i < N; i++) {`   `        ``if` `(MaxVal < lis[i] + lds[i] - 1) {` `            ``MaxVal = lis[i] + lds[i] - 1;` `            ``inx = i;` `        ``}` `    ``}`   `    ``// Stores the count of elements in` `    ``// increasing order in Bitonic subsequence` `    ``int` `ct1 = lis[inx];` `    ``vector<``int``> res;`   `    ``// Store the increasing subsequence` `    ``for` `(``int` `i = inx; i >= 0 && ct1 > 0; i--) {`   `        ``if` `(lis[i] == ct1) {`   `            ``res.push_back(arr[i]);`   `            ``ct1--;` `        ``}` `    ``}`   `    ``// Sort the bitonic subsequence` `    ``// to arrange smaller elements` `    ``// at the beginning` `    ``reverse(res.begin(), res.end());`   `    ``// Stores the count of elements in` `    ``// decreasing order in Bitonic subsequence` `    ``int` `ct2 = lds[inx] - 1;` `    ``for` `(``int` `i = inx; i < N && ct2 > 0; i++) {`   `        ``if` `(lds[i] == ct2) {`   `            ``res.push_back(arr[i]);`   `            ``ct2--;` `        ``}` `    ``}`   `    ``// Print the longest` `    ``// bitonic sequence` `    ``printRes(res);` `}`   `// Driver Code` `int` `main()` `{`   `    ``int` `arr[] = { 80, 60, 30, 40, 20, 10 };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``printLBS(arr, N);` `}`

## Java

 `// Java program to implement` `// the above approach` `import` `java.util.*;` `class` `GFG {`   `// Function to print the longest` `// bitonic subsequence` `static` `void` `printRes(Vector res)` `{` `    ``Enumeration enu = res.elements();` `    ``while` `(enu.hasMoreElements())` `    ``{` `        ``System.out.print(enu.nextElement() + ``" "``);` `    ``}` `}`   `// Function to generate the longest` `// bitonic subsequence` `static` `void` `printLBS(``int` `arr[], ``int` `N)` `{`   `    ``// Store the lengths of LIS` `    ``// ending at every index` `    ``int` `lis[] = ``new` `int``[N];`   `    ``// Store the lengths of LDS` `    ``// ending at every index` `    ``int` `lds[] = ``new` `int``[N];`   `    ``for``(``int` `i = ``0``; i < N; i++)` `    ``{` `        ``lis[i] = lds[i] = ``1``;` `    ``}`   `    ``// Compute LIS for all indices` `    ``for``(``int` `i = ``0``; i < N; i++)` `    ``{` `        ``for``(``int` `j = ``0``; j < i; j++)` `        ``{` `            ``if` `(arr[j] < arr[i]) ` `            ``{` `                ``if` `(lis[i] < lis[j] + ``1``)` `                    ``lis[i] = lis[j] + ``1``;` `            ``}` `        ``}` `    ``}`   `    ``// Compute LDS for all indices` `    ``for``(``int` `i = N - ``1``; i >= ``0``; i--) ` `    ``{` `        ``for``(``int` `j = N - ``1``; j > i; j--)` `        ``{` `            ``if` `(arr[j] < arr[i])` `            ``{` `                ``if` `(lds[i] < lds[j] + ``1``)` `                    ``lds[i] = lds[j] + ``1``;` `            ``}` `        ``}` `    ``}`   `    ``// Find the index having` `    ``// maximum value of` `    ``// lis[i] + lds[i] - 1` `    ``int` `MaxVal = arr[``0``], inx = ``0``;` `    ``for``(``int` `i = ``0``; i < N; i++)` `    ``{` `        ``if` `(MaxVal < lis[i] + lds[i] - ``1``)` `        ``{` `            ``MaxVal = lis[i] + lds[i] - ``1``;` `            ``inx = i;` `        ``}` `    ``}`   `    ``// Stores the count of elements in` `    ``// increasing order in Bitonic subsequence` `    ``int` `ct1 = lis[inx];` `    ``Vector res = ``new` `Vector();`   `    ``// Store the increasing subsequence` `    ``for``(``int` `i = inx; i >= ``0` `&& ct1 > ``0``; i--)` `    ``{` `        ``if` `(lis[i] == ct1) ` `        ``{` `            ``res.add(arr[i]);`   `            ``ct1--;` `        ``}` `    ``}`   `    ``// Sort the bitonic subsequence` `    ``// to arrange smaller elements` `    ``// at the beginning` `    ``Collections.reverse(res);` `    `  `    ``// Stores the count of elements in` `    ``// decreasing order in Bitonic subsequence` `    ``int` `ct2 = lds[inx] - ``1``;` `    ``for``(``int` `i = inx; i < N && ct2 > ``0``; i++) ` `    ``{` `        ``if` `(lds[i] == ct2)` `        ``{` `            ``res.add(arr[i]);` `            ``ct2--;` `        ``}` `    ``}`   `    ``// Print the longest` `    ``// bitonic sequence` `    ``printRes(res);` `}`   `// Driver Code` `public` `static` `void` `main(String[] args)` `{` `    ``int` `arr[] = { ``80``, ``60``, ``30``, ``40``, ``20``, ``10` `};` `    ``int` `N = arr.length;` `    `  `    ``printLBS(arr, N);` `}` `}`   `// This code is contributed by chitranayal`

## Python3

 `# Python3 program to implement ` `# the above approach`   `# Function to print the longest ` `# bitonic subsequence ` `def` `printRes(res):` `    `  `    ``n ``=` `len``(res)` `    ``for` `i ``in` `range``(n):` `        ``print``(res[i], end ``=` `" "``)` `        `  `# Function to generate the longest ` `# bitonic subsequence ` `def` `printLBS(arr, N):` `    `  `    ``# Store the lengths of LIS ` `    ``# ending at every index ` `    ``lis ``=` `[``0``] ``*` `N` `    `  `    ``# Store the lengths of LDS ` `    ``# ending at every index ` `    ``lds ``=` `[``0``] ``*` `N` `    `  `    ``for` `i ``in` `range``(N):` `        ``lis[i] ``=` `lds[i] ``=` `1` `        `  `    ``# Compute LIS for all indices ` `    ``for` `i ``in` `range``(N):` `        ``for` `j ``in` `range``(i):` `            ``if` `arr[j] < arr[i]:` `                ``if` `lis[i] < lis[j] ``+` `1``:` `                    ``lis[i] ``=` `lis[j] ``+` `1` `                `  `    ``# Compute LDS for all indices` `    ``for` `i ``in` `range``(N ``-` `1``, ``-``1``, ``-``1``):` `        ``for` `j ``in` `range``(N ``-` `1``, i, ``-``1``):` `            ``if` `arr[j] < arr[i]:` `                ``if` `lds[i] < lds[j] ``+` `1``:` `                    ``lds[i] ``=` `lds[j] ``+` `1` `                    `  `    ``# Find the index having ` `    ``# maximum value of ` `    ``# lis[i]+lds[i]+1 ` `    ``MaxVal ``=` `arr[``0``]` `    ``inx ``=` `0` `    `  `    ``for` `i ``in` `range``(N):` `        ``if` `MaxVal < lis[i] ``+` `lds[i] ``-` `1``:` `            ``MaxVal ``=` `lis[i] ``+` `lds[i] ``-` `1` `            ``inx ``=` `i` `            `  `    ``# Stores the count of elements in ` `    ``# increasing order in Bitonic subsequence` `    ``ct1 ``=` `lis[inx]` `    ``res ``=` `[]` `    `  `    ``i ``=` `inx` `    `  `    ``# Store the increasing subsequence ` `    ``while` `i >``=` `0` `and` `ct1 > ``0``:` `        ``if` `lis[i] ``=``=` `ct1:` `            ``res.append(arr[i])` `            ``ct1 ``-``=` `1` `            `  `        ``i ``-``=` `1` `        `  `    ``# Sort the bitonic subsequence ` `    ``# to arrange smaller elements ` `    ``# at the beginning ` `    ``res.reverse()` `    `  `    ``# Stores the count of elements in ` `    ``# decreasing order in Bitonic subsequence` `    ``ct2 ``=` `lds[inx] ``-` `1` `    ``i ``=` `inx` `    `  `    ``while` `i < N ``and` `ct2 > ``0``:` `        ``if` `lds[i] ``=``=` `ct2:` `            ``res.append(arr[i])` `            ``ct2 ``-``=` `1` `            `  `        ``i ``+``=` `1` `    `  `    ``# Print the longest ` `    ``# bitonic sequence ` `    ``printRes(res)` `    `  `# Driver code` `arr ``=` `[ ``80``, ``60``, ``30``, ``40``, ``20``, ``10` `]` `N ``=` `len``(arr)`   `printLBS(arr, N)`   `# This code is contributed by Stuti Pathak`

## C#

 `// C# program to implement` `// the above approach` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG{`   `    ``// Function to print the longest` `    ``// bitonic subsequence` `    ``static` `void` `printRes(List<``int``> res)` `    ``{` `        ``foreach``(``int` `enu ``in` `res)` `        ``{` `            ``Console.Write(enu + ``" "``);` `        ``}` `    ``}`   `    ``// Function to generate the longest` `    ``// bitonic subsequence` `    ``static` `void` `printLBS(``int``[] arr, ``int` `N)` `    ``{`   `        ``// Store the lengths of LIS` `        ``// ending at every index` `        ``int``[] lis = ``new` `int``[N];`   `        ``// Store the lengths of LDS` `        ``// ending at every index` `        ``int``[] lds = ``new` `int``[N];`   `        ``for` `(``int` `i = 0; i < N; i++) ` `        ``{` `            ``lis[i] = lds[i] = 1;` `        ``}`   `        ``// Compute LIS for all indices` `        ``for` `(``int` `i = 0; i < N; i++) ` `        ``{` `            ``for` `(``int` `j = 0; j < i; j++) ` `            ``{` `                ``if` `(arr[j] < arr[i]) ` `                ``{` `                    ``if` `(lis[i] < lis[j] + 1)` `                        ``lis[i] = lis[j] + 1;` `                ``}` `            ``}` `        ``}`   `        ``// Compute LDS for all indices` `        ``for` `(``int` `i = N - 1; i >= 0; i--) ` `        ``{` `            ``for` `(``int` `j = N - 1; j > i; j--) ` `            ``{` `                ``if` `(arr[j] < arr[i]) ` `                ``{` `                    ``if` `(lds[i] < lds[j] + 1)` `                        ``lds[i] = lds[j] + 1;` `                ``}` `            ``}` `        ``}`   `        ``// Find the index having` `        ``// maximum value of` `        ``// lis[i] + lds[i] - 1` `        ``int` `MaxVal = arr[0], inx = 0;` `        ``for` `(``int` `i = 0; i < N; i++) ` `        ``{` `            ``if` `(MaxVal < lis[i] + lds[i] - 1) ` `            ``{` `                ``MaxVal = lis[i] + lds[i] - 1;` `                ``inx = i;` `            ``}` `        ``}`   `        ``// Stores the count of elements in` `        ``// increasing order in Bitonic subsequence` `        ``int` `ct1 = lis[inx];` `        ``List<``int``> res = ``new` `List<``int``>();`   `        ``// Store the increasing subsequence` `        ``for` `(``int` `i = inx; i >= 0 && ct1 > 0; i--) ` `        ``{` `            ``if` `(lis[i] == ct1) ` `            ``{` `                ``res.Add(arr[i]);` `                ``ct1--;` `            ``}` `        ``}`   `        ``// Sort the bitonic subsequence` `        ``// to arrange smaller elements` `        ``// at the beginning` `        ``res.Reverse();`   `        ``// Stores the count of elements in` `        ``// decreasing order in Bitonic subsequence` `        ``int` `ct2 = lds[inx] - 1;` `        ``for` `(``int` `i = inx; i < N && ct2 > 0; i++) ` `        ``{` `            ``if` `(lds[i] == ct2) ` `            ``{` `                ``res.Add(arr[i]);` `                ``ct2--;` `            ``}` `        ``}`   `        ``// Print the longest` `        ``// bitonic sequence` `        ``printRes(res);` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `Main(String[] args)` `    ``{` `        ``int``[] arr = {80, 60, 30, 40, 20, 10};` `        ``int` `N = arr.Length;` `        ``printLBS(arr, N);` `    ``}` `}`   `// This code is contributed by Amit Katiyar`

## Javascript

 ``

Output:

`80 60 30 20 10`

Time Complexity: O(N2
Auxiliary Space: O(N)