Sum of elements in 1st array such that number of elements less than or equal to them in 2nd array is maximum
Given two unsorted arrays arr1[] and arr2[], the task is to find the sum of elements of arr1[] such that the number of elements less than or equal to them in arr2[] is maximum.
Examples:
Input: arr1[] = {1, 2, 3, 4, 7, 9}, arr2[] = {0, 1, 2, 1, 1, 4}
Output: 20
Below table shows the count of elements in arr2[] which are ? the elements of arr1[]
arr1[i] |
Count |
1 |
4 |
2 |
5 |
3 |
5 |
4 |
6 |
7 |
6 |
9 |
6 |
Count for 4, 7 and 9 is maximum.
Hence, the resultant sum is 4 + 7 + 9 = 20.
Input:arr1[] = {5, 10, 2, 6, 1, 8, 6, 12}, arr2[] = {6, 5, 11, 4, 2, 3, 7}
Output: 12
Approach: The idea behind an efficient solution for the above problem is to use hashing of the second array and then find the cumulative sum of a hashed array. After that, the count of elements in the second array less than or equal to elements of 1st array can easily be calculated. This will give a frequency array which represents the count of elements in the second array less than or equal to elements of 1st array from where the sum of elements of the first array can be calculated corresponding to the maximum frequency in the frequency array.
Below is the implementation of the above approach:
C++
#include <iostream>
using namespace std;
#define MAX 100000
int findSumofEle( int arr1[], int m,
int arr2[], int n)
{
int hash[MAX] = { 0 };
for ( int i = 0; i < n; i++)
hash[arr2[i]]++;
for ( int i = 1; i < MAX; i++)
hash[i] = hash[i] + hash[i - 1];
int maximumFreq = 0;
for ( int i = 0; i < m; i++)
maximumFreq = max(maximumFreq, hash[arr1[i]]);
int sumOfElements = 0;
for ( int i = 0; i < m; i++)
sumOfElements += (maximumFreq == hash[arr1[i]]) ? arr1[i] : 0;
return sumOfElements;
}
int main()
{
int arr1[] = { 2, 5, 6, 8 };
int arr2[] = { 4, 10 };
int m = sizeof (arr1) / sizeof (arr1[0]);
int n = sizeof (arr2) / sizeof (arr2[0]);
cout << findSumofEle(arr1, m, arr2, n);
return 0;
}
|
Java
class GFG
{
static int MAX = 100000 ;
static int findSumofEle( int arr1[], int m,
int arr2[], int n)
{
int hash[] = new int [MAX];
for ( int i = 0 ; i < n; i++)
{
hash[arr2[i]]++;
}
for ( int i = 1 ; i < MAX; i++)
{
hash[i] = hash[i] + hash[i - 1 ];
}
int maximumFreq = 0 ;
for ( int i = 0 ; i < m; i++)
{
maximumFreq = Math.max(maximumFreq, hash[arr1[i]]);
}
int sumOfElements = 0 ;
for ( int i = 0 ; i < m; i++)
{
sumOfElements += (maximumFreq == hash[arr1[i]]) ? arr1[i] : 0 ;
}
return sumOfElements;
}
public static void main(String[] args)
{
int arr1[] = { 2 , 5 , 6 , 8 };
int arr2[] = { 4 , 10 };
int m = arr1.length;
int n = arr2.length;
System.out.println(findSumofEle(arr1, m, arr2, n));
}
}
|
Python3
MAX = 100000
def findSumofEle(arr1, m, arr2, n):
hash = [ 0 for i in range ( MAX )]
for i in range (n):
hash [arr2[i]] + = 1
for i in range ( 1 , MAX , 1 ):
hash [i] = hash [i] + hash [i - 1 ]
maximumFreq = 0
for i in range (m):
maximumFreq = max (maximumFreq,
hash [arr1[i]])
sumOfElements = 0
for i in range (m):
if (maximumFreq = = hash [arr1[i]]):
sumOfElements + = arr1[i]
return sumOfElements
if __name__ = = '__main__' :
arr1 = [ 2 , 5 , 6 , 8 ]
arr2 = [ 4 , 10 ]
m = len (arr1)
n = len (arr2)
print (findSumofEle(arr1, m, arr2, n))
|
C#
using System;
class GFG
{
static int MAX = 100000;
static int findSumofEle( int [] arr1, int m,
int [] arr2, int n)
{
int [] hash = new int [MAX];
for ( int i = 0; i < n; i++)
{
hash[arr2[i]]++;
}
for ( int i = 1; i < MAX; i++)
{
hash[i] = hash[i] + hash[i - 1];
}
int maximumFreq = 0;
for ( int i = 0; i < m; i++)
{
maximumFreq = Math.Max(maximumFreq, hash[arr1[i]]);
}
int sumOfElements = 0;
for ( int i = 0; i < m; i++)
{
sumOfElements += (maximumFreq == hash[arr1[i]]) ? arr1[i] : 0;
}
return sumOfElements;
}
public static void Main()
{
int [] arr1 = {2, 5, 6, 8};
int [] arr2 = {4, 10};
int m = arr1.Length;
int n = arr2.Length;
Console.WriteLine(findSumofEle(arr1, m, arr2, n));
}
}
|
PHP
<?php
$MAX = 10000;
function findSumofEle( $arr1 , $m , $arr2 , $n )
{
$hash = array_fill (0, $GLOBALS [ 'MAX' ], 0);
for ( $i = 0; $i < $n ; $i ++)
$hash [ $arr2 [ $i ]]++;
for ( $i = 1; $i < $GLOBALS [ 'MAX' ]; $i ++)
$hash [ $i ] = $hash [ $i ] + $hash [ $i - 1];
$maximumFreq = 0;
for ( $i = 0; $i < $m ; $i ++)
$maximumFreq = max( $maximumFreq ,
$hash [ $arr1 [ $i ]]);
$sumOfElements = 0;
for ( $i = 0; $i < $m ; $i ++)
$sumOfElements += ( $maximumFreq == $hash [ $arr1 [ $i ]]) ?
$arr1 [ $i ] : 0;
return $sumOfElements ;
}
$arr1 = array ( 2, 5, 6, 8 );
$arr2 = array ( 4, 10 );
$m = count ( $arr1 );
$n = count ( $arr2 );
echo findSumofEle( $arr1 , $m , $arr2 , $n );
?>
|
Javascript
<script>
function findSumofEle(arr1, m, arr2, n)
{
let MAX = 100000;
let hash = new Array(MAX);
for (let i = 0; i < MAX; i++)
hash[i] = 0;
for (let i = 0; i < n; i++)
hash[arr2[i]]++;
for (let i = 1; i < MAX; i++)
hash[i] = hash[i] + hash[i - 1];
let maximumFreq = 0;
for (let i = 0; i < m; i++)
{
maximumFreq = Math.max(maximumFreq,
hash[arr1[i]]);
}
let sumOfElements = 0;
for (let i = 0; i < m; i++)
{
if (maximumFreq == hash[arr1[i]])
sumOfElements += arr1[i];
}
return sumOfElements;
}
let arr1 = [ 2, 5, 6, 8 ];
let arr2 = [ 4, 10 ];
let m = arr1.length;
let n = arr2.length;
document.write(findSumofEle(arr1, m, arr2, n));
</script>
|
Time Complexity: O(MAX)
Auxiliary Space: O(MAX), since MAX extra space has been taken.
Another efficient approach: Using Standard Template Library (STL)
In this approach, we will first sort the 2nd array. Then we will iterate in the first array and for each element in the first array, we will find the count of smaller elements in arr2 using lower_bound STL in O(log(n)) time. If the count of such elements is maximum then we can say that the corresponding element in arr1 will be in the answer. In this way, we keep on iterating in the 1st array and try to find the elements with the maximum count in the 2nd array and we will add those elements to the answer. The time complexity of this approach is O(n*log(n)+m*log(n)) and hence it is better than the previous approach for small values of n and m. Also, the auxiliary space in this approach is O(1) which is better than the previous approach.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findSumofEle( int arr1[], int m, int arr2[], int n)
{
int maxi=INT_MIN;
int ans=0;
sort(arr2,arr2+n);
for ( int i=0;i<m;i++)
{
int y = lower_bound(arr2,arr2+n,arr1[i]+1)-arr2;
y=y-1;
if (y>maxi)
{
maxi=y;
ans=arr1[i];
}
else if (y==maxi)
{
ans+=arr1[i];
}
}
return ans;
}
int main()
{
int arr1[] = {5, 10, 2, 6, 1, 8, 6, 12};
int arr2[] = { 6, 5, 11, 4, 2, 3, 7};
int m = sizeof (arr1) / sizeof (arr1[0]);
int n = sizeof (arr2) / sizeof (arr2[0]);
cout << findSumofEle(arr1, m, arr2, n);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int lower_bound( int [] arr, int elem)
{
for ( int i = 0 ; i < arr.length; i++)
if (elem <= arr[i])
return i;
return arr.length;
}
static int findSumofEle( int [] arr1, int m, int [] arr2,
int n)
{
int maxi = Integer.MIN_VALUE;
int ans = 0 ;
Arrays.sort(arr2);
for ( int i = 0 ; i < m; i++)
{
int y = lower_bound(arr2, arr1[i] + 1 );
y = y - 1 ;
if (y > maxi) {
maxi = y;
ans = arr1[i];
}
else if (y == maxi) {
ans += arr1[i];
}
}
return ans;
}
public static void main(String[] args)
{
int [] arr1 = { 5 , 10 , 2 , 6 , 1 , 8 , 6 , 12 };
int [] arr2 = { 6 , 5 , 11 , 4 , 2 , 3 , 7 };
int m = arr1.length;
int n = arr2.length;
System.out.println(findSumofEle(arr1, m, arr2, n));
}
}
|
Python3
def lower_bound(arr, n, elem):
for i in range (n):
if (arr[i] > = elem):
return i;
return n;
def findSumofEle(arr1, m, arr2, n):
maxi = - 1000000 ;
ans = 0 ;
arr2.sort();
for i in range (m):
y = lower_bound(arr2, n, arr1[i] + 1 );
y = y - 1 ;
if (y > maxi):
maxi = y;
ans = arr1[i];
elif (y = = maxi):
ans + = arr1[i];
return ans;
arr1 = [ 5 , 10 , 2 , 6 , 1 , 8 , 6 , 12 ];
arr2 = [ 6 , 5 , 11 , 4 , 2 , 3 , 7 ];
m = len (arr1);
n = len (arr2)
print (findSumofEle(arr1, m, arr2, n));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int lower_bound( int [] arr, int elem)
{
for ( int i = 0; i < arr.Length; i++)
if (elem <= arr[i])
return i;
return arr.Length;
}
static int findSumofEle( int [] arr1, int m, int [] arr2, int n)
{
int maxi= Int32.MinValue;
int ans=0;
Array.Sort(arr2);
for ( int i=0;i<m;i++)
{
int y = lower_bound(arr2, arr1[i]+1);
y=y-1;
if (y>maxi)
{
maxi=y;
ans=arr1[i];
}
else if (y==maxi)
{
ans+=arr1[i];
}
}
return ans;
}
public static void Main( string [] args)
{
int [] arr1 = {5, 10, 2, 6, 1, 8, 6, 12};
int [] arr2 = { 6, 5, 11, 4, 2, 3, 7};
int m = arr1.Length;
int n = arr2.Length;
Console.WriteLine(findSumofEle(arr1, m, arr2, n));
}
}
|
Javascript
function lower_bound(arr, n, elem)
{
for ( var i = 0; i < n; i++)
if (arr[i] >= elem)
return i;
return n;
}
function findSumofEle(arr1, m, arr2, n)
{
let maxi= -1000000;
let ans=0;
arr2.sort();
for ( var i=0;i<m;i++)
{
var y = lower_bound(arr2, n, arr1[i]+1);
y = y - 1;
if (y > maxi)
{
maxi = y;
ans = arr1[i];
}
else if (y==maxi)
{
ans+=arr1[i];
}
}
return ans;
}
let arr1 = [5, 10, 2, 6, 1, 8, 6, 12];
let arr2 = [ 6, 5, 11, 4, 2, 3, 7];
let m = arr1.length;
let n = arr2.length;
console.log(findSumofEle(arr1, m, arr2, n));
|
Time Complexity: O(n*log(n)+m*log(n)) where m and n are size of the array.
Auxiliary Space: O(1)
Last Updated :
29 Aug, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...