Find whether a subarray is in form of a mountain or not - GeeksforGeeks

25 Aug, 2021
We are given an array of integers and a range, we need to find whether the subarray which falls in this range has values in the form of a mountain or not. All values of the subarray are said to be in the form of a mountain if either all values are increasing or decreasing or first increasing and then decreasing. More formally a subarray [a1, a2, a3 ... aN] is said to be in form of a mountain if there exist an integer K, 1 <= K <= N such that, a1 <= a2 <= a3 .. <= aK >= a(K+1) >= a(K+2) .... >= aN 
Examples: 
Input : Arr[]  = [2 3 2 4 4 6 3 2], Range = [0, 2]
Output :  Yes

Explanation: The output is yes , subarray is [2 3 2], 
so subarray first increases and then decreases

Input:  Arr[] = [2 3 2 4 4 6 3 2], Range = [2, 7]
Output: Yes

Explanation: The output is yes , subarray is [2 4 4 6 3 2], 
so subarray first increases and then decreases


Input: Arr[]= [2 3 2 4 4 6 3 2], Range = [1, 3]
Output: no

Explanation: The output is no, subarray is [3 2 4], 
so subarray is not in the form above stated
Solution: 
Approach: The problem has multiple queries so for each query the solution should be calculated with least possible time complexity. So create two extra spaces of the length of the original array. For every element find the last index on the left side which is increasing i.e. greater than its previous element and find the element on the right side will store the first index on the right side which is decreasing i.e. greater than its next element. If these value can be calculated for every index in constant time then for every given range the answer can be given in constant time.
Algorithm: Create two extra spaces of length n,left and right and a extra variable lastptrInitialize left[0] = 0 and lastptr = 0Traverse the original array from second index to the endFor every index check if it is greater than the previous element, if yes then update the lastptr with the current index.For every index store the lastptr in left[i]initialize right[N-1] = N-1 and lastptr = N-1Traverse the original array from second last index to the startFor every index check if it is greater than the next element, if yes then update the lastptr with the current index.For every index store the lastptr in right[i]Now process the queriesfor every query l, r, if right[l] >= left[r] then print yes else no
Create two extra spaces of length n,left and right and a extra variable lastptrInitialize left[0] = 0 and lastptr = 0Traverse the original array from second index to the endFor every index check if it is greater than the previous element, if yes then update the lastptr with the current index.For every index store the lastptr in left[i]initialize right[N-1] = N-1 and lastptr = N-1Traverse the original array from second last index to the startFor every index check if it is greater than the next element, if yes then update the lastptr with the current index.For every index store the lastptr in right[i]Now process the queriesfor every query l, r, if right[l] >= left[r] then print yes else no
Create two extra spaces of length n,left and right and a extra variable lastptr
Initialize left[0] = 0 and lastptr = 0
Traverse the original array from second index to the end
For every index check if it is greater than the previous element, if yes then update the lastptr with the current index.
For every index store the lastptr in left[i]
initialize right[N-1] = N-1 and lastptr = N-1
Traverse the original array from second last index to the start
For every index check if it is greater than the next element, if yes then update the lastptr with the current index.
For every index store the lastptr in right[i]
Now process the queries
for every query l, r, if right[l] >= left[r] then print yes else no
Implementation:
C++
Java
Python3
C#
Javascript
// C++ program to check whether a subarray is in// mountain form or not#include <bits/stdc++.h>using namespace std; // Utility method to construct left and right arrayint preprocess(int arr[], int N, int left[], int right[]){    // Initialize first left index as that index only    left[0] = 0;    int lastIncr = 0;     for (int i = 1; i < N; i++)    {        // if current value is greater than previous,        // update last increasing        if (arr[i] > arr[i - 1])            lastIncr = i;        left[i] = lastIncr;    }     // Initialize last right index as that index only    right[N - 1] = N - 1;    int firstDecr = N - 1;     for (int i = N - 2; i >= 0; i--)    {        // if current value is greater than next,        // update first decreasing        if (arr[i] > arr[i + 1])            firstDecr = i;        right[i] = firstDecr;    }} // Method returns true if arr[L..R] is in mountain formbool isSubarrayMountainForm(int arr[], int left[],                             int right[], int L, int R){    // return true only if right at starting range is    // greater than left at ending range    return (right[L] >= left[R]);} //    Driver code to test above methodsint main(){    int arr[] = {2, 3, 2, 4, 4, 6, 3, 2};    int N = sizeof(arr) / sizeof(int);     int left[N], right[N];    preprocess(arr, N, left, right);     int L = 0;    int R = 2;    if (isSubarrayMountainForm(arr, left, right, L, R))        cout << "Subarray is in mountain form\n";    else        cout << "Subarray is not in mountain form\n";     L = 1;    R = 3;    if (isSubarrayMountainForm(arr, left, right, L, R))        cout << "Subarray is in mountain form\n";    else        cout << "Subarray is not in mountain form\n";     return 0;}
// Java program to check whether a subarray is in// mountain form or notclass SubArray{    // Utility method to construct left and right array    static void preprocess(int arr[], int N, int left[], int right[])    {        // initialize first left index as that index only        left[0] = 0;        int lastIncr = 0;             for (int i = 1; i < N; i++)        {            // if current value is greater than previous,            // update last increasing            if (arr[i] > arr[i - 1])                    lastIncr = i;            left[i] = lastIncr;        }             // initialize last right index as that index only        right[N - 1] = N - 1;        int firstDecr = N - 1;             for (int i = N - 2; i >= 0; i--)        {            // if current value is greater than next,            // update first decreasing            if (arr[i] > arr[i + 1])                    firstDecr = i;            right[i] = firstDecr;        }    }         // method returns true if arr[L..R] is in mountain form    static boolean isSubarrayMountainForm(int arr[], int left[],                                    int right[], int L, int R)    {        // return true only if right at starting range is        // greater than left at ending range        return (right[L] >= left[R]);    }         public static void main(String[] args)    {        int arr[] = {2, 3, 2, 4, 4, 6, 3, 2};        int N = arr.length;        int left[] = new int[N];        int right[] = new int[N];        preprocess(arr, N, left, right);        int L = 0;        int R = 2;                 if (isSubarrayMountainForm(arr, left, right, L, R))            System.out.println("Subarray is in mountain form");        else            System.out.println("Subarray is not in mountain form");             L = 1;        R = 3;             if (isSubarrayMountainForm(arr, left, right, L, R))            System.out.println("Subarray is in mountain form");        else            System.out.println("Subarray is not in mountain form");    }}// This Code is Contributed by Saket Kumar
# Python 3 program to check whether a subarray is in# mountain form or not # Utility method to construct left and right arraydef preprocess(arr, N, left, right):    # initialize first left index as that index only    left[0] = 0    lastIncr = 0     for i in range(1,N):        # if current value is greater than previous,        # update last increasing        if (arr[i] > arr[i - 1]):            lastIncr = i        left[i] = lastIncr     # initialize last right index as that index only    right[N - 1] = N - 1    firstDecr = N - 1     i = N - 2    while(i >= 0):        # if current value is greater than next,        # update first decreasing        if (arr[i] > arr[i + 1]):            firstDecr = i        right[i] = firstDecr        i -= 1 # method returns true if arr[L..R] is in mountain formdef isSubarrayMountainForm(arr, left, right, L, R):         # return true only if right at starting range is    # greater than left at ending range    return (right[L] >= left[R]) # Driver codeif __name__ == '__main__':    arr = [2, 3, 2, 4, 4, 6, 3, 2]    N = len(arr)     left = [0 for i in range(N)]    right = [0 for i in range(N)]    preprocess(arr, N, left, right)     L = 0    R = 2    if (isSubarrayMountainForm(arr, left, right, L, R)):        print("Subarray is in mountain form")    else:        print("Subarray is not in mountain form")     L = 1    R = 3    if (isSubarrayMountainForm(arr, left, right, L, R)):        print("Subarray is in mountain form")    else:        print("Subarray is not in mountain form") # This code is contributed by# Surendra_Gangwar
// C# program to check whether// a subarray is in mountain// form or notusing System; class GFG{         // Utility method to construct    // left and right array    static void preprocess(int []arr, int N,                           int []left, int []right)    {        // initialize first left        // index as that index only        left[0] = 0;        int lastIncr = 0;             for (int i = 1; i < N; i++)        {            // if current value is            // greater than previous,            // update last increasing            if (arr[i] > arr[i - 1])                    lastIncr = i;            left[i] = lastIncr;        }             // initialize last right        // index as that index only        right[N - 1] = N - 1;        int firstDecr = N - 1;             for (int i = N - 2; i >= 0; i--)        {            // if current value is            // greater than next,            // update first decreasing            if (arr[i] > arr[i + 1])                    firstDecr = i;            right[i] = firstDecr;        }    }         // method returns true if    // arr[L..R] is in mountain form    static bool isSubarrayMountainForm(int []arr, int []left,                                       int []right, int L, int R)    {        // return true only if right at        // starting range is greater        // than left at ending range        return (right[L] >= left[R]);    }              // Driver Code    static public void Main ()    {        int []arr = {2, 3, 2, 4,                     4, 6, 3, 2};        int N = arr.Length;        int []left = new int[N];        int []right = new int[N];        preprocess(arr, N, left, right);                 int L = 0;        int R = 2;                 if (isSubarrayMountainForm(arr, left,                                   right, L, R))            Console.WriteLine("Subarray is in " +                                "mountain form");        else            Console.WriteLine("Subarray is not " +                              "in mountain form");             L = 1;        R = 3;             if (isSubarrayMountainForm(arr, left,                                   right, L, R))            Console.WriteLine("Subarray is in " +                                "mountain form");        else            Console.WriteLine("Subarray is not " +                              "in mountain form");    }} // This code is contributed by aj_36
<script>    // Javascript program to check whether    // a subarray is in mountain    // form or not         // Utility method to construct    // left and right array    function preprocess(arr, N, left, right)    {        // initialize first left        // index as that index only        left[0] = 0;        let lastIncr = 0;               for (let i = 1; i < N; i++)        {            // if current value is            // greater than previous,            // update last increasing            if (arr[i] > arr[i - 1])                    lastIncr = i;            left[i] = lastIncr;        }               // initialize last right        // index as that index only        right[N - 1] = N - 1;        let firstDecr = N - 1;               for (let i = N - 2; i >= 0; i--)        {            // if current value is            // greater than next,            // update first decreasing            if (arr[i] > arr[i + 1])                    firstDecr = i;            right[i] = firstDecr;        }    }           // method returns true if    // arr[L..R] is in mountain form    function isSubarrayMountainForm(arr, left, right, L, R)    {        // return true only if right at        // starting range is greater        // than left at ending range        return (right[L] >= left[R]);    }         let arr = [2, 3, 2, 4, 4, 6, 3, 2];    let N = arr.length;    let left = new Array(N);    let right = new Array(N);    preprocess(arr, N, left, right);     let L = 0;    let R = 2;     if (isSubarrayMountainForm(arr, left, right, L, R))      document.write("Subarray is in " + "mountain form" + "</br>");    else      document.write("Subarray is not " + "in mountain form" + "</br>");     L = 1;    R = 3;     if (isSubarrayMountainForm(arr, left, right, L, R))      document.write("Subarray is in " + "mountain form");    else      document.write("Subarray is not " + "in mountain form");     </script>
Output:
Subarray is in mountain form
Subarray is not in mountain form
Complexity Analysis: Time Complexity:O(n). Only two traversals are needed so the time complexity is O(n).Space Complexity:O(n). Two extra space of length n is required so the space complexity is O(n).
Time Complexity:O(n). Only two traversals are needed so the time complexity is O(n).
Space Complexity:O(n). Two extra space of length n is required so the space complexity is O(n).
This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
jit_t
SURENDRA_GANGWAR
andrew1234
mukesh07
arorakashish0911
adnanirshad158
Amazon
array-range-queries
FactSet
Advanced Data Structure
Arrays
Amazon
FactSet
Arrays
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Agents in Artificial Intelligence
Decision Tree Introduction with example
AVL Tree | Set 2 (Deletion)
Red-Black Tree | Set 2 (Insert)
Segment Tree | Set 1 (Sum of given range)
Arrays in Java
Arrays in C/C++
Maximum and minimum of an array using minimum number of comparisons
Write a program to reverse an array or string
Program for array rotation