
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Min Max Range Queries in Array in C++
Given an array Arr[] containing N elements. The goal is to find the minimum and maximum value from indexes of query.
According to the query we are given starting index and ending indexes.
For Example
In − Arr[] = { 1, 2, 3, 4, 5 } QStart = 1 QEnd = 4
Out −
Minimum Value : 2
Maximum Value : 5
Explanation −In the above queries the starting index is 1 and ending index is 4. Between these two indexes, minimum value in Arr is 2 and maximum value is 5
In − Arr[] = { 10, 12, 3, 2, 5, 18 } QStart = 2 QEnd = 5
Out −
Minimum Value : 2
Maximum Value : 18
Explanation − In the above queries the starting index is 2 and ending index is 5. Between these two indexes, minimum value in Arr is 2 and maximum value is 18
Approach used in the below program is as follows −
In this approach we will use segment trees for the range lpos to rpos to find the minimum and maximum values in the given query range.
Take the input array Arr[] and query indexes QStart and QEnd.
Take the result of type value.
Structure value is used to store minimum and maximum value found in an array using a given query.
Structure value is used to store minimum and maximum value found in an array using a given query.
Function minMax(struct value *root1, int num, int qStart1, int qEnd1) takes query indexes and finds minimum and maximum in an array between index range qStart1 and qEnd1.
Check if ( qStart1 < 0 OR qEnd1 > num-1 OR qStart1 > qEnd1 ). If true then input range in the query is invalid.
Otherwise, call minmaxFind(root1, 0, num-1, qStart1, qEnd1, 0).
Function minmaxFind(struct value *root, int startT, int endT, int qStart, int qEnd, int pos) is a recursive function. It takes a pointer to segment tree- root, starting and ending index of current value as startT and endT.
It also takes a starting and ending index in query range. The current index of value in the segment tree has index pos.
If (qStart <= startT) AND if( qEnd >= endT) then the segment of current value is part of the given range. So return minimum and maximum in that value.
If it is outside the range then update the current value with minVal and maxVal.
If current part overlaps with given range then :-
Take middl = startT + ( endT - startT )/2.
Take p1 and p2 as 2*pos+1 and =2*pos+2.
Update lpos as lpos = minmaxFind(root, startT, middl, qStart, qEnd, p1) and rpos as minmaxFind(root, middl+1, endT, qStart, qEnd, p2).
Set temp.minVal as minimum of lpos.minVal and rpos.minVal.
Set temp.maxVal as maximum of lpos.maxVal and rpos.maxVal.
Return temp.
Function segmentTree(int arr2[], int startT2, int endT2, struct value *root2, int pos2) is used to construct a segment tree for array arr2[] with index range as startT2 and endT2 and current value position is pos2.
Function *createTree(int arr0[], int num0) is used to construct a segment tree from a given array arr0. This function allocates memory for segment trees and calls segmentTree() for memory allocation.
Example
#include<bits/stdc++.h> using namespace std; struct value{ int minVal; int maxVal; }; struct value minmaxFind(struct value *root, int startT, int endT, int qStart, int qEnd, int pos){ struct value temp, lpos ,rpos; if (qStart <= startT) { if( qEnd >= endT) { return root[pos]; } } if (endT < qStart || startT > qEnd) { temp.minVal = 9999; temp.maxVal = -9999; return temp; } int middl = startT + ( endT - startT )/2; int p1=2*pos+1; int p2=2*pos+2; lpos = minmaxFind(root, startT, middl, qStart, qEnd, p1); rpos = minmaxFind(root, middl+1, endT, qStart, qEnd, p2); temp.minVal = (lpos.minVal<rpos.minVal) ? lpos.minVal : rpos.minVal ; temp.maxVal = (lpos.maxVal>rpos.maxVal) ? lpos.maxVal : rpos.maxVal ; return temp; } struct value minMax(struct value *root1, int num, int qStart1, int qEnd1){ struct value temp1; if (qStart1 < 0 || qEnd1 > num-1 || qStart1 > qEnd1){ cout<<"Please enter Valid input!!"; temp1.minVal = 9999; temp1.maxVal = -9999; return temp1; } return minmaxFind(root1, 0, num-1, qStart1, qEnd1, 0); } void segmentTree(int arr2[], int startT2, int endT2, struct value *root2, int pos2){ if (startT2 == endT2) { root2[pos2].minVal = arr2[startT2]; root2[pos2].maxVal = arr2[startT2]; return ; } int p1=pos2*2+1; int p2=pos2*2+2; int middl2 = startT2+(endT2-startT2)/2; segmentTree(arr2, startT2, middl2, root2, p1); segmentTree(arr2, middl2+1, endT2, root2, p2); root2[pos2].minVal = root2[p1].minVal<root2[p2].minVal ? root2[p1].minVal : root2[p2].minVal; root2[pos2].maxVal = root2[p1].maxVal>root2[p2].maxVal ? root2[p1].maxVal : root2[p2].maxVal; } struct value *createTree(int arr0[], int num0) { int height = (int)(ceil(log2(num0))); int maxS = 2*(int)pow(2, height) - 1; struct value *root0 = new struct value[maxS]; segmentTree(arr0, 0, num0-1, root0, 0); return root0; } int main() { int Arr[] = { 1, 2, 3, 4, 5 }; int length = sizeof(Arr)/sizeof(Arr[0]); struct value *tree = createTree(Arr, length); int QStart = 1; int QEnd = 4; struct value answer=minMax(tree, length, QStart, QEnd); cout<<"Minimum Value : "<<answer.minVal<<endl; cout<<"Maximum Value : "<<answer.maxVal; return 0; }
Output
If we run the above code it will generate the following Output
Minimum Value : 2 Maximum Value : 5