Divide array into increasing and decreasing subsequence without changing the order
Last Updated :
23 Jul, 2022
Given a merged sequence which consists of two sequences which got merged, one of them was strictly increasing and the other was strictly decreasing. Elements of increasing sequence were inserted between elements of the decreasing one without changing the order.
Sequences [1, 3, 4] and [10, 4, 2] can produce the following resulting sequences:
[10, 1, 3, 4, 2, 4], [1, 3, 4, 10, 4, 2].
The following sequence cannot be the result of these insertions:
[1, 10, 4, 4, 3, 2] because the order of elements in the increasing sequence was changed.
Given a merged sequence, the task is to find any two suitable initial sequences, one of them should be strictly increasing, and another should be strictly decreasing.
Note: An empty sequence and the sequence consisting of one element can be considered as increasing or decreasing.
Examples:
Input: arr[] = {5, 1, 3, 6, 8, 2, 9, 0, 10}
Output: [1, 3, 6, 8, 9, 10] [5, 2, 0]
Input: arr[] = {1, 2, 4, 0, 2}
Output: -1
No such sequences possible.
Method 1: We can modify Longest Increasing Sequence) and solve the required problem. It will take O(nlogn) time.
Method 2: We can also solve this problem only in a single traversal. The Idea used here is that maintain two sorted arrays.
For a new element x,
- If it can be appended to only one of the arrays then append it.
- If it can be appended to neither, then the answer is -1.
- If it can be appended to both then check the next element y, if y > x then append x to the increasing one otherwise append x to the decreasing one.
Now when we encounter an element which can be included in both the sequence we need to decide based on the next element's value. Let's consider a situation where we need to iterate over the remaining value x,y,z where ( x < z < y) and we have already the last element of the increasing and decreasing sequence as inc and dec respectively from the visited portion of the array.
Case 1 : x<y and inc<x<dec
so we can include x in any sequence.
If we include it in decreasing sequence then dec will become x. And then for y we have only one choice i.e. to include it in increasing sequence as y>dec and inc becomes y. If we do this we cannot insert z in any sequence as z>dec and z<inc.
But if we include x to increasing sequence (inc becomes x) and y to decreasing sequence (dec becomes y) following the same logic then we can place z in any sequence and get an answer.
Case 2 : x>=y and inc<x<dec
it follows the same logic as above.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
// Function to print strictly increasing and
// strictly decreasing sequence if possible
void Find_Sequence(int arr[], int n)
{
// Arrays to store strictly increasing and
// decreasing sequence
vector<int> inc_arr, dec_arr;
// Initializing last element of both sequence
int flag = 0;
long inc = -1, dec = 1e7;
// Iterating through the array
for (int i = 0; i < n; i++)
{
// If current element can be appended
// to both the sequences
if (inc < arr[i] && arr[i] < dec)
{
// If next element is greater than
// the current element
// Then append it to the strictly
// increasing array
if (arr[i] < arr[i + 1])
{
inc = arr[i];
inc_arr.emplace_back(arr[i]);
}
// Otherwise append it to the
// strictly decreasing array
else
{
dec = arr[i];
dec_arr.emplace_back(arr[i]);
}
}
// If current element can be appended
// to the increasing sequence only
else if (inc < arr[i])
{
inc = arr[i];
inc_arr.emplace_back(arr[i]);
}
// If current element can be appended
// to the decreasing sequence only
else if (dec > arr[i])
{
dec = arr[i];
dec_arr.emplace_back(arr[i]);
}
// Else we can not make such sequences
// from the given array
else
{
cout << -1 << endl;
flag = 1;
break;
}
}
// Print the required sequences
if (!flag)
{
for (auto i = inc_arr.begin();
i != inc_arr.end(); i++)
cout << *i << " ";
cout << endl;
for (auto i = dec_arr.begin();
i != dec_arr.end(); i++)
cout << *i << " ";
cout << endl;
}
}
// Driver code
int main()
{
int arr[] = { 5, 1, 3, 6, 8, 2, 9, 0, 10 };
int n = sizeof(arr) / sizeof(arr[0]);
Find_Sequence(arr, n);
}
// This code is contributed by sanjeev2552
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function to print strictly increasing and
// strictly decreasing sequence if possible
static void Find_Sequence(int[] arr, int n)
{
// Arrays to store strictly increasing and
// decreasing sequence
Vector<Integer> inc_arr = new Vector<>(),
dec_arr = new Vector<>();
// Initializing last element of both sequence
int flag = 0;
long inc = -1, dec = (long) 1e7;
// Iterating through the array
for (int i = 0; i < n; i++)
{
// If current element can be appended
// to both the sequences
if (inc < arr[i] && arr[i] < dec)
{
// If next element is greater than
// the current element
// Then append it to the strictly
// increasing array
if (arr[i] < arr[i + 1])
{
inc = arr[i];
inc_arr.add(arr[i]);
}
// Otherwise append it to the
// strictly decreasing array
else
{
dec = arr[i];
dec_arr.add(arr[i]);
}
}
// If current element can be appended
// to the increasing sequence only
else if (inc < arr[i])
{
inc = arr[i];
inc_arr.add(arr[i]);
}
// If current element can be appended
// to the decreasing sequence only
else if (dec > arr[i])
{
dec = arr[i];
dec_arr.add(arr[i]);
}
// Else we can not make such sequences
// from the given array
else
{
System.out.println(-1);
flag = 1;
break;
}
}
// Print the required sequences
if (flag == 0)
{
for (int i : inc_arr)
System.out.print(i + " ");
System.out.println();
for (int i : dec_arr)
System.out.print(i + " ");
System.out.println();
}
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 5, 1, 3, 6, 8, 2, 9, 0, 10 };
int n = arr.length;
Find_Sequence(arr, n);
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 implementation of the approach
# Function to print strictly increasing and
# strictly decreasing sequence if possible
def Find_Sequence(array, n):
# Arrays to store strictly increasing and
# decreasing sequence
inc_arr, dec_arr =[], []
# Initializing last element of both sequence
inc, dec = -1, 1e7
# Iterating through the array
for i in range(n):
# If current element can be appended
# to both the sequences
if inc < array[i] < dec:
# If next element is greater than
# the current element
# Then append it to the strictly
# increasing array
if array[i] < array[i + 1]:
inc = array[i]
inc_arr.append(array[i])
# Otherwise append it to the
# strictly decreasing array
else:
dec = array[i]
dec_arr.append(array[i])
# If current element can be appended
# to the increasing sequence only
elif inc < array[i]:
inc = array[i]
inc_arr.append(array[i])
# If current element can be appended
# to the decreasing sequence only
elif dec > array[i]:
dec = array[i]
dec_arr.append(array[i])
# Else we can not make such sequences
# from the given array
else:
print('-1')
break
# Print the required sequences
else:
print(inc_arr, dec_arr)
# Driver code
arr = [5, 1, 3, 6, 8, 2, 9, 0, 10]
n = len(arr)
Find_Sequence(arr, n)
C#
// C# implementation of the approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
// Function to print strictly increasing and
// strictly decreasing sequence if possible
static void Find_Sequence(int[] arr, int n)
{
// Arrays to store strictly increasing and
// decreasing sequence
ArrayList inc_arr = new ArrayList();
ArrayList dec_arr = new ArrayList();
// Initializing last element of both sequence
int flag = 0;
long inc = -1, dec = (long)1e7;
// Iterating through the array
for(int i = 0; i < n; i++)
{
// If current element can be appended
// to both the sequences
if (inc < arr[i] && arr[i] < dec)
{
// If next element is greater than
// the current element
// Then append it to the strictly
// increasing array
if (arr[i] < arr[i + 1])
{
inc = arr[i];
inc_arr.Add(arr[i]);
}
// Otherwise append it to the
// strictly decreasing array
else
{
dec = arr[i];
dec_arr.Add(arr[i]);
}
}
// If current element can be appended
// to the increasing sequence only
else if (inc < arr[i])
{
inc = arr[i];
inc_arr.Add(arr[i]);
}
// If current element can be appended
// to the decreasing sequence only
else if (dec > arr[i])
{
dec = arr[i];
dec_arr.Add(arr[i]);
}
// Else we can not make such sequences
// from the given array
else
{
Console.Write(-1);
flag = 1;
break;
}
}
// Print the required sequences
if (flag == 0)
{
foreach(int i in inc_arr)
Console.Write(i + " ");
Console.Write('\n');
foreach(int i in dec_arr)
Console.Write(i + " ");
Console.Write('\n');
}
}
// Driver Code
public static void Main(string[] args)
{
int[] arr = { 5, 1, 3, 6, 8,
2, 9, 0, 10 };
int n = arr.Length;
Find_Sequence(arr, n);
}
}
// This code is contributed by rutvik_56
PHP
<?php
// Php implementation of the approach
// Function to print strictly increasing and
// strictly decreasing sequence if possible
function Find_Sequence($arr, $n)
{
// Arrays to store strictly increasing and
// decreasing sequence
$inc_arr = array(); $dec_arr = array();
// Initializing last element of both sequence
$inc = -1; $dec = 1e7;
// Iterating through the array
for ($i = 0; $i < $n ; $i++)
{
// If current element can be appended
// to both the sequences
if ($inc < $arr[$i] && $arr[$i] < $dec)
{
// If next element is greater than
// the current element
// Then append it to the strictly
// increasing array
if ($arr[$i] < $arr[$i + 1])
{
$inc = $arr[$i];
array_push($inc_arr, $arr[$i]);
}
// Otherwise append it to the
// strictly decreasing array
else
{
$dec = $arr[$i];
array_push($dec_arr, $arr[$i]);
}
}
// If current element can be appended
// to the increasing sequence only
else if ($inc < $arr[$i])
{
$inc = $arr[$i];
array_push($inc_arr, $arr[$i]);
}
// If current element can be appended
// to the decreasing sequence only
else if($dec > $arr[$i])
{
$dec = $arr[$i];
array_push($dec_arr, $arr[$i]);
}
// Else we can not make such sequences
// from the given array
else
{
echo '-1';
break;
}
}
// Print the required sequences
print_r($inc_arr);
print_r($dec_arr);
}
// Driver code
$arr = array(5, 1, 3, 6, 8, 2, 9, 0, 10);
$n = count($arr);
Find_Sequence($arr, $n);
// This code is contributed by Ryuga
?>
JavaScript
<script>
// Javascript implementation of the approach
// Function to print strictly increasing and
// strictly decreasing sequence if possible
function Find_Sequence(arr, n)
{
// Arrays to store strictly increasing and
// decreasing sequence
let inc_arr =[],
dec_arr = [];
// Initializing last element of both sequence
let flag = 0;
let inc = -1, dec = 1e7;
// Iterating through the array
for (let i = 0; i < n; i++)
{
// If current element can be appended
// to both the sequences
if (inc < arr[i] && arr[i] < dec)
{
// If next element is greater than
// the current element
// Then append it to the strictly
// increasing array
if (arr[i] < arr[i + 1])
{
inc = arr[i];
inc_arr.push(arr[i]);
}
// Otherwise append it to the
// strictly decreasing array
else
{
dec = arr[i];
dec_arr.push(arr[i]);
}
}
// If current element can be appended
// to the increasing sequence only
else if (inc < arr[i])
{
inc = arr[i];
inc_arr.push(arr[i]);
}
// If current element can be appended
// to the decreasing sequence only
else if (dec > arr[i])
{
dec = arr[i];
dec_arr.push(arr[i]);
}
// Else we can not make such sequences
// from the given array
else
{
document.write(-1);
flag = 1;
break;
}
}
// Print the required sequences
if (flag == 0)
{
document.write("[");
for (let i in inc_arr)
document.write( inc_arr[i] + " ");
document.write("] ");
document.write("[");
for (let i in dec_arr)
document.write( dec_arr[i] + " ");
document.write("]");
}
}
// Driver Code
let arr = [ 5, 1, 3, 6, 8, 2, 9, 0, 10 ];
let n = arr.length;
Find_Sequence(arr, n);
// This code is contributed by target_2.
</script>
Output:
[1, 3, 6, 8, 9, 10] [5, 2, 0]
Time Complexity : O(n) ,where n is size of given array.
Space Complexity : O(n) ,extra space required to store strictly increasing and decreasing sequence.
Similar Reads
Split the array elements into strictly increasing and decreasing sequence
Given an array of N elements. The task is to split the elements into two arrays say a1[] and a2[] such that one contains strictly increasing elements and the other contains strictly decreasing elements and a1.size() + a2.size() = a.size(). If it is not possible to do so, print -1 or else print both
7 min read
Min operations to empty an array by erasing any increasing subsequence
Given array A[] of size N, the task is to find the number of operations to empty the array by performing the following operation one or more times. In one operation choose any strictly increasing subsequence and delete it from A[].Examples:Input: A[] = {2, 1, 4, 5, 3}Output: 2Explanation: Following
5 min read
Longest non-decreasing Subsequence with adjacent differences
Given an array arr[] of N elements, the task is to find the length of the longest non-decreasing subsequence such that the differences between adjacent elements are non-decreasing. For indices i, j, and k: i < j < k, ai â aj ⤠aj â ak Examples: Input: N = 9, arr[] = [1, 3, 5, 4, 7, 8, 10, 6, 9
15+ min read
Minimum number of elements which are not part of Increasing or decreasing subsequence in array
Given an array of n elements. Make strictly increasing and strictly decreasing subsequences from the array such that each array element belongs to increasing subsequence or decreasing subsequence, but not both, or can be part of none of the subsequence. Minimize the number of elements which are not
12 min read
Find longest bitonic sequence such that increasing and decreasing parts are from two different arrays
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
10 min read
Minimum steps for increasing and decreasing Array to reach either 0 or N
Given an integer N and two arrays increasing[] and decreasing[], such that they have elements from 1 to N only. The task is to find the minimum number of steps for each element of the two arrays to reach either 0 or N. A step is defined as follows: In one step, all the elements of the increasing[] a
7 min read
Maximum sum subsequence of any size which is decreasing-increasing alternatively
Given an array of integers arr[], find the subsequence with maximum sum whose elements are first decreasing, then increasing, or vice versa, The subsequence can start anywhere in the main sequence, not necessarily at the first element of the main sequence. A sequence {x1, x2, .. xn} is an alternatin
15+ min read
Check if given Array can be rearranged as increasing, decreasing or a hill sequence
Given an array arr[] of size N. The task is to find the number of sequences in which any one of the following conditions is met: The given sequence can be re-arranged into strictly increasing order, orThe given sequence can be re-arranged into strictly decreasing order, orThe given sequence can be r
10 min read
Minimum in an array which is first decreasing then increasing
Given an array of N integers where array elements form a strictly decreasing and increasing sequence. The task is to find the smallest number in such an array. Constraints: N >= 3 Examples: Input: a[] = {2, 1, 2, 3, 4}Output: 1Input: a[] = {8, 5, 4, 3, 4, 10}Output: 3 A naive approach is to linea
12 min read
Minimize the number of strictly increasing subsequences in an array | Set 2
Given an array arr[] of size N, the task is to print the minimum possible count of strictly increasing subsequences present in the array. Note: It is possible to swap the pairs of array elements. Examples: Input: arr[] = {2, 1, 2, 1, 4, 3}Output: 2Explanation: Sorting the array modifies the array to
6 min read