Open In App

# Print Longest Bitonic subsequence (Space Optimized Approach)

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)