Related Articles
Find longest bitonic sequence such that increasing and decreasing parts are from two different arrays
• Difficulty Level : Medium
• Last Updated : 01 Oct, 2020

We are given two arrays, we need to find the longest possible bitonic sequence such that the increasing part must be from the first array and should be a subsequence of the first array. Similarly, the decreasing part of must be from the second array and should be a subsequence of it.
Examples:

```Input : arr1[] = {1, 5, 2, 4, 3, 5},
arr2[] = {8, 6, 4, 7, 3, 2}
Output : 1, 2, 4, 5, 8, 6, 4, 3, 2

Input : arr1[] = {2, 0, 1, 3, 4},
arr2[] = {5, 3, 2, 1}
Output : 0, 1, 2, 3, 4, 5, 3, 2, 1

```

The idea is to use the largest increasing sequence from array1 and the largest decreasing sequence from array2 and then combine both to get our result.

## C++

 `// CPP to find largest bitonic sequence such that` `#include ` `using` `namespace` `std;`   `vector<``int``> res;`   `// utility Binary search` `int` `GetCeilIndex(``int` `arr[], vector<``int``>& T, ``int` `l, ` `                                   ``int` `r, ``int` `key)` `{` `    ``while` `(r - l > 1) {` `        ``int` `m = l + (r - l) / 2;` `        ``if` `(arr[T[m]] >= key)` `            ``r = m;` `        ``else` `            ``l = m;` `    ``}` `    ``return` `r;` `}`   `// function to find LIS in reverse form` `void` `LIS(``int` `arr[], ``int` `n)` `{` `    ``// Add boundary case, when array n is zero` `    ``// Depend on smart pointers` `    ``vector<``int``> tailIndices(n, 0); ``// Initialized with 0` `    ``vector<``int``> prevIndices(n, -1); ``// initialized with -1`   `    ``int` `len = 1; ``// it will always point to empty location` `    ``for` `(``int` `i = 1; i < n; i++) {`   `        ``// new smallest value` `        ``if` `(arr[i] < arr[tailIndices])             ` `            ``tailIndices = i;`   `        ``// arr[i] wants to extend largest subsequence` `        ``else` `if` `(arr[i] > arr[tailIndices[len - 1]]) {            ` `            ``prevIndices[i] = tailIndices[len - 1];` `            ``tailIndices[len++] = i;` `        ``} ` `         `  `        ``// arr[i] wants to be a potential candidate of` `        ``// future subsequence` `        ``// It will replace ceil value in tailIndices` `        ``else` `{` `            ``int` `pos = GetCeilIndex(arr, tailIndices, -1, ` `                                        ``len - 1, arr[i]);` `            ``prevIndices[i] = tailIndices[pos - 1];` `            ``tailIndices[pos] = i;` `        ``}` `    ``}`   `    ``// put LIS into vector` `    ``for` `(``int` `i = tailIndices[len - 1]; i >= 0; i = prevIndices[i])` `        ``res.push_back(arr[i]);` `}`   `// function for finding longest bitonic seq` `void` `longestBitonic(``int` `arr1[], ``int` `n1, ``int` `arr2[], ``int` `n2)` `{` `    ``// find LIS of array 1 in reverse form` `    ``LIS(arr1, n1);`   `    ``// reverse res to get LIS of first array` `    ``reverse(res.begin(), res.end());`   `    ``// reverse array2 and find its LIS` `    ``reverse(arr2, arr2 + n2);` `    ``LIS(arr2, n2);`   `    ``// print result` `    ``for` `(``int` `i = 0; i < res.size(); i++)` `        ``cout << res[i] << ``" "``;` `}`   `// driver preogram` `int` `main()` `{` `    ``int` `arr1[] = { 1, 2, 4, 3, 2 };` `    ``int` `arr2[] = { 8, 6, 4, 7, 8, 9 };` `    ``int` `n1 = ``sizeof``(arr1) / ``sizeof``(arr1);` `    ``int` `n2 = ``sizeof``(arr2) / ``sizeof``(arr2);` `    ``longestBitonic(arr1, n1, arr2, n2);` `    ``return` `0;` `}`

## Java

 `// Java to find largest bitonic sequence such that` `import` `java.util.*;`   `class` `GFG ` `{` `    ``static` `Vector res = ``new` `Vector<>();`   `    ``// utility Binary search` `    ``static` `Integer GetCeilIndex(Integer[] arr, Integer[] T, ` `                                ``Integer l, Integer r, Integer key) ` `    ``{` `        ``while` `(r - l > ``1``) ` `        ``{` `            ``Integer m = l + (r - l) / ``2``;` `            ``if` `(arr[T[m]] >= key)` `                ``r = m;` `            ``else` `                ``l = m;` `        ``}` `        ``return` `r;` `    ``}`   `    ``// function to find LIS in reverse form` `    ``static` `void` `LIS(Integer[] arr, Integer n)` `    ``{`   `        ``// Add boundary case, when array n is zero` `        ``// Depend on smart pointers` `        ``Integer[] tailIndices = ``new` `Integer[n];` `        ``Integer[] prevIndices = ``new` `Integer[n];` `        ``Arrays.fill(tailIndices, ``0``); ``// Initialized with 0` `        ``Arrays.fill(prevIndices, -``1``); ``// initialized with -1`   `        ``Integer len = ``1``; ``// it will always point to empty location` `        ``for` `(Integer i = ``1``; i < n; i++) ` `        ``{` `            ``// new smallest value` `            ``if` `(arr[i] < arr[tailIndices[``0``]])` `                ``tailIndices[``0``] = i;`   `            ``// arr[i] wants to extend largest subsequence` `            ``else` `if` `(arr[i] > arr[tailIndices[len - ``1``]]) ` `            ``{` `                ``prevIndices[i] = tailIndices[len - ``1``];` `                ``tailIndices[len++] = i;` `            ``}`   `            ``// arr[i] wants to be a potential candidate of` `            ``// future subsequence` `            ``// It will replace ceil value in tailIndices` `            ``else` `            ``{` `                ``Integer pos = GetCeilIndex(arr, ` `                            ``tailIndices, -``1``, len - ``1``, arr[i]);` `                ``prevIndices[i] = tailIndices[pos - ``1``];` `                ``tailIndices[pos] = i;` `            ``}` `        ``}`   `        ``// put LIS into vector` `        ``for` `(Integer i = tailIndices[len - ``1``]; i >= ``0``; i = prevIndices[i])` `            ``res.add(arr[i]);` `    ``}`   `    ``// function for finding longest bitonic seq` `    ``static` `void` `longestBitonic(Integer[] arr1, Integer n1,` `                                ``Integer[] arr2, Integer n2)` `    ``{` `        ``// find LIS of array 1 in reverse form` `        ``LIS(arr1, n1);`   `        ``// reverse res to get LIS of first array` `        ``Collections.reverse(res);`   `        ``// reverse array2 and find its LIS` `        ``Collections.reverse(Arrays.asList(arr2));` `        ``LIS(arr2, n2);`   `        ``// print result` `        ``for` `(Integer i = ``0``; i < res.size(); i++)` `            ``System.out.print(res.elementAt(i) + ``" "``);` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args) ` `    ``{` `        ``Integer[] arr1 = { ``1``, ``2``, ``4``, ``3``, ``2` `};` `        ``Integer[] arr2 = { ``8``, ``6``, ``4``, ``7``, ``8``, ``9` `};` `        ``Integer n1 = arr1.length;` `        ``Integer n2 = arr2.length;` `        ``longestBitonic(arr1, n1, arr2, n2);` `    ``}` `}`   `// This code is contributed by` `// sanjeev2552`

## Python3

 `# Python3 to find largest bitonic sequence such that` `res ``=` `[]`   `# utility Binary search` `def` `GetCeilIndex(arr,T, l,r, key):` `    ``while` `(r ``-` `l > ``1``):` `        ``m ``=` `l ``+` `(r ``-` `l) ``/``/` `2``;` `        ``if` `(arr[T[m]] >``=` `key):` `            ``r ``=` `m` `        ``else``:` `            ``l ``=` `m` `    ``return` `r`   `# function to find LIS in reverse form` `def` `LIS(arr, n):` `    `  `    ``# Add boundary case, when array n is zero` `    ``# Depend on smart pointers` `    ``tailIndices ``=` `[``0``]``*``(n) ``#Initialized with 0` `    ``prevIndices ``=` `[``-``1``]``*``(n) ``#initialized with -1`   `    ``leN` `=` `1` `# it will always poto empty location` `    ``for` `i ``in` `range``(``1``, n):`   `        ``# new smallest value` `        ``if` `(arr[i] < arr[tailIndices[``0``]]):` `            ``tailIndices[``0``] ``=` `i`   `        ``# arr[i] wants to extend largest subsequence` `        ``elif` `(arr[i] > arr[tailIndices[``leN` `-` `1``]]):` `            ``prevIndices[i] ``=` `tailIndices[``leN` `-` `1``]` `            ``tailIndices[``leN``] ``=` `i` `            ``leN` `+``=` `1`   `        ``# arr[i] wants to be a potential candidate of` `        ``# future subsequence` `        ``# It will replace ceil value in tailIndices` `        ``else``:` `            ``pos ``=` `GetCeilIndex(arr, tailIndices, ``-``1``,` `                               ``leN` `-` `1``, arr[i])` `            ``prevIndices[i] ``=` `tailIndices[pos ``-` `1``]` `            ``tailIndices[pos] ``=` `i`   `    ``# put LIS into vector` `    ``i ``=` `tailIndices[``leN` `-` `1``]` `    ``while``(i >``=` `0``):` `        `  `        ``# print(i)` `        ``res.append(arr[i])` `        ``i ``=` `prevIndices[i]`   `# function for finding longest bitonic seq` `def` `longestBitonic(arr1, n1, arr2, n2):` `    ``global` `res` `    `  `    ``# find LIS of array 1 in reverse form` `    ``LIS(arr1, n1)`   `    ``# reverse res to get LIS of first array` `    ``res ``=` `res[::``-``1``]`   `    ``# reverse array2 and find its LIS` `    ``arr2 ``=` `arr2[::``-``1``]` `    ``LIS(arr2, n2)`   `    ``# print result` `    ``for` `i ``in` `res:` `        ``print``(i,end``=``" "``)`   `# Driver program`   `arr1 ``=` `[``1``, ``2``, ``4``, ``3``, ``2``]` `arr2 ``=` `[``8``, ``6``, ``4``, ``7``, ``8``, ``9``]` `n1 ``=` `len``(arr1)` `n2 ``=` `len``(arr2)` `longestBitonic(arr1, n1, arr2, n2);`   `# This code is contributed by mohit kumar 29    `

## C#

 `// C# to find largest bitonic ` `// sequence ` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG{ `   `static` `List<``int``> res = ``new` `List<``int``>(); `   `// Reverse array` `static` `int``[] reverse(``int` `[]a) ` `{` `  ``int` `i, n = a.Length, t;` `  ``for` `(i = 0; i < n / 2; i++) ` `  ``{` `    ``t = a[i];` `    ``a[i] = a[n - i - 1];` `    ``a[n - i - 1] = t;` `  ``}` `  ``return` `a;` `}` `  `  `// Utility Binary search ` `static` `int` `GetCeilIndex(``int``[] arr, ``int``[] T, ` `                        ``int` `l, ``int` `r, ``int` `key) ` `{ ` `  ``while` `(r - l > 1) ` `  ``{ ` `    ``int` `m = l + (r - l) / 2; ` `    ``if` `(arr[T[m]] >= key) ` `      ``r = m; ` `    ``else` `      ``l = m; ` `  ``} ` `  ``return` `r; ` `} `   `// Function to find LIS in reverse form ` `static` `void` `LIS(``int``[] arr, ``int` `n) ` `{` `  ``// Add boundary case, ` `  ``// when array n is zero ` `  ``// Depend on smart pointers ` `  ``int``[] tailIndices = ``new` `int``[n]; ` `  ``int``[] prevIndices = ``new` `int``[n]; ` `  ``for``(``int` `i = 0; i < n; i++)` `  ``{` `    ``tailIndices[i] = 0;` `    ``prevIndices[i] = -1;` `  ``}` `  ``int` `len = 1; ` `  `  `  ``// It will always point ` `  ``// to empty location ` `  ``for` `(``int` `i = 1; i < n; i++) ` `  ``{ ` `    ``// New smallest value ` `    ``if` `(arr[i] < arr[tailIndices]) ` `      ``tailIndices = i; `   `    ``// arr[i] wants to extend ` `    ``// largest subsequence ` `    ``else` `if` `(arr[i] > arr[tailIndices[len - 1]]) ` `    ``{ ` `      ``prevIndices[i] = tailIndices[len - 1]; ` `      ``tailIndices[len++] = i; ` `    ``} `   `    ``// arr[i] wants to be ` `    ``// a potential candidate of ` `    ``// future subsequence ` `    ``// It will replace ceil ` `    ``// value in tailIndices ` `    ``else` `    ``{ ` `      ``int` `pos = GetCeilIndex(arr, tailIndices, ` `                             ``-1, len - 1, arr[i]); ` `      ``prevIndices[i] = tailIndices[pos - 1]; ` `      ``tailIndices[pos] = i; ` `    ``} ` `  ``} `   `  ``// Put LIS into vector ` `  ``for` `(``int` `i = tailIndices[len - 1]; ` `           ``i >= 0; i = prevIndices[i]) ` `    ``res.Add(arr[i]); ` `} `   `// Function for finding longest bitonic seq ` `static` `void` `longestBitonic(``int``[] arr1, ``int` `n1,  ` `                           ``int``[] arr2, ``int` `n2) ` `{ ` `  ``// Find LIS of array 1 ` `  ``// in reverse form ` `  ``LIS(arr1, n1); `   `  ``// Reverse res to get ` `  ``// LIS of first array ` `  ``res.Reverse();`   `  ``// Reverse array2 and ` `  ``// find its LIS ` `  ``arr2 = reverse(arr2); ` `  ``LIS(arr2, n2); `   `  ``// Print result ` `  ``for` `(``int` `i = 0; i < res.Count; i++) ` `    ``Console.Write(res[i] + ``" "``); ` `} `   `// Driver Code ` `public` `static` `void` `Main(String[] args) ` `{ ` `  ``int``[] arr1 = {1, 2, 4, 3, 2}; ` `  ``int``[] arr2 = {8, 6, 4, 7, 8, 9}; ` `  ``int` `n1 = arr1.Length; ` `  ``int` `n2 = arr2.Length; ` `  ``longestBitonic(arr1, n1, arr2, n2); ` `} ` `} `   `// This code is contributed by gauravrajput1`

Output:

```1 2 3 8 6 4

```

Time Complexity : O(n Log n)
Please note that O(n Log n) implementation of LIS is used