Given an array arr containing N positive integers and the number of queries Q, for each query task is to find the maximum pair sum in the given index range [L, R] where L and R are the respective low and high indices.
Examples:
Input: arr = {3, 4, 5, 6, 7, 8}, Q[][2] = [[0, 3], [3, 5]]
Output:
11
15
Explanation:
For the first query, subarray is [3, 4, 5, 6]
All the pairs are (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)
Hence the maximum pair sum = (5 + 6) = 11
For the second query, subarray is [6, 7, 8]
All the pairs of the subarray are (6, 7), (6, 8), (7, 8)
Hence the maximum pair sum = (7 + 8) = 15
Naive Approach: For each query range, do the following
- Find the maximum and the second maximum in the given query range.
- Sum of maximum and second maximum will be the maximum pair sum of the given range.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct node {
int f;
int s;
};
void findSum( int * arr, int n,
int Q, node* query)
{
for ( int i = 0; i < Q; i++) {
int f, s;
f = s = 0;
for ( int j = query[i].f;
j <= query[i].s;
j++) {
if (arr[j] >= f) {
s = f;
f = arr[j];
}
else if (arr[j] > s)
s = arr[j];
}
cout << (f + s) << endl;
}
}
int main()
{
int arr[] = { 3, 4, 5, 6, 7, 8 }, Q = 2;
int n = sizeof (arr) / sizeof (arr[0]);
node query[Q];
query[0] = { 0, 3 };
query[1] = { 3, 5 };
findSum(arr, n, Q, query);
}
|
Java
class GFG{
static class node {
int f;
int s;
public node( int f, int s) {
this .f = f;
this .s = s;
}
};
static void findSum( int []arr, int n,
int Q, node []query)
{
for ( int i = 0 ; i < Q; i++) {
int f, s;
f = s = 0 ;
for ( int j = query[i].f;
j <= query[i].s;
j++) {
if (arr[j] >= f) {
s = f;
f = arr[j];
}
else if (arr[j] > s)
s = arr[j];
}
System.out.print((f + s) + "\n" );
}
}
public static void main(String[] args)
{
int arr[] = { 3 , 4 , 5 , 6 , 7 , 8 }, Q = 2 ;
int n = arr.length;
node []query = new node[ 2 ];
query[ 0 ] = new node( 0 , 3 );
query[ 1 ] = new node( 3 , 5 );
findSum(arr, n, Q, query);
}
}
|
Python3
from pickle import NONE
class node:
def __init__( self , f, s):
self .f = f
self .s = s
def findSum(arr, n, Q, query):
for i in range (Q):
f,s = 0 , 0
for j in range (query[i].f,query[i].s + 1 ):
if (arr[j] > = f):
s = f
f = arr[j]
elif (arr[j] > s):
s = arr[j]
print (f + s)
arr = [ 3 , 4 , 5 , 6 , 7 , 8 ]
Q = 2
n = len (arr)
query = [ None ] * Q
query[ 0 ] = node( 0 , 3 )
query[ 1 ] = node( 3 , 5 )
findSum(arr, n, Q, query)
|
C#
using System;
class GFG{
class node {
public int f;
public int s;
public node( int f, int s) {
this .f = f;
this .s = s;
}
};
static void findSum( int []arr, int n,
int Q, node []query)
{
for ( int i = 0; i < Q; i++) {
int f, s;
f = s = 0;
for ( int j = query[i].f;
j <= query[i].s;
j++) {
if (arr[j] >= f) {
s = f;
f = arr[j];
}
else if (arr[j] > s)
s = arr[j];
}
Console.Write((f + s) + "\n" );
}
}
public static void Main(String[] args)
{
int []arr = { 3, 4, 5, 6, 7, 8 };
int Q = 2;
int n = arr.Length;
node []query = new node[2];
query[0] = new node( 0, 3 );
query[1] = new node(3, 5 );
findSum(arr, n, Q, query);
}
}
|
Javascript
<script>
class node {
constructor(f,s) {
this .f = f;
this .s = s;
}
}
function findSum(arr,n,Q,query)
{
for (let i = 0; i < Q; i++) {
let f, s;
f = s = 0;
for (let j = query[i].f;j <= query[i].s;j++) {
if (arr[j] >= f) {
s = f;
f = arr[j];
}
else if (arr[j] > s)
s = arr[j];
}
document.write(f + s, "</br>" );
}
}
let arr = [ 3, 4, 5, 6, 7, 8 ], Q = 2;
let n = arr.length;
let query = new Array(Q);
query[0] = new node( 0, 3 );
query[1] = new node( 3, 5 );
findSum(arr, n, Q, query);
</script>
|
Performance Analysis:
- Time Complexity: In the above approach, we are looper over the array of length N for each of Q query. Thus the time complexity would be O(N*Q).
- Auxiliary Space: In the above approach there is no extra space used, therefore the Auxiliary Space complexity will be O(1).
Efficient Approach: The idea is to use the segment tree where each node of the segment tree store two values:
- Maximum of the given below subtree
- Second maximum of the given below subtree
- Time Complexity: In the above approach, we are building a segment tree which is of time complexity O(N) Then for each of Q queries, we find the solution in O(logN) time. So overall time complexity is O(N+Q*logN)
- Auxiliary Space Complexity: In the above approach, we are using extra space for storing the segment tree which is taking (4 * N + 1) space. So Auxiliary space complexity is O(N)