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 lastptr
- Initilize 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 pervious element, if yes then update the lastptr with the current index.
- For every index store the lastptr in left[i]
- initilize 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/C++
// 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 array
int
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
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 to test above methods
int
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;
}
chevron_rightfilter_noneJava
// Java program to check whether a subarray is in
// mountain form or not
class
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
chevron_rightfilter_nonePython3
# Python 3 program to check whether a subarray is in
# mountain form or not
# Utility method to construct left and right array
def
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 form
def
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 code
if
__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
chevron_rightfilter_noneC#
// C# program to check whether
// a subarray is in mountain
// form or not
using
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
chevron_rightfilter_none -
Output:
Subarray is in mountain form Subarray is not in mountain form
-
Complexity Analysis:
- Time Complexiity: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 Complexiity: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 contribute.geeksforgeeks.org or mail your article to contribute@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.
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.