# Maximum subset sum having difference between its maximum and minimum in range [L, R]

• Last Updated : 04 Apr, 2022

Given an array arr[] of N positive integers and a range [L, R], the task is to find the maximum subset-sum such that the difference between the maximum and minimum elements of the subset lies in the given range.

Examples:

Input: arr[] = {6, 5, 0, 9, 1}, L = 0, R = 3
Output: 15
Explanation: The subset {6, 9} of the given array has the difference between maximum and minimum elements as 3 which lies in the given range [0, 3] and the sum of the elements as 15 which is the maximum possible.

Input: arr[] = {5, 10, 15, 20, 25}, L = 1, R = 2
Output: 0
Explanation: There exist no valid subsets.

Approach: The given problem can be solved with the help of a Binary Search after sorting the given array. Below are the steps to follow:

• Sort the given array in non-decreasing order.
• Create a prefix sum array sum[] using the algorithm discussed here.
• Traverse the array using a variable i for all values of i in the range [0, N).
• For each i, find the index j of the largest integer such that arr[j] <= arr[i] + R. This can be done using the upper_bound function.
• Maintain a variable ans, which stores the maximum subset-sum. Initially, ans = 0.
• If the subarray arr[i, j] forms a valid subset, update the value of ans to the max of ans and sum of the subarray arr[i, j].
• The value stored in ans is the required answer.

Below is the implementation of the above approach:

## CPP

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to find Maximum Subset Sum such``// that the difference between maximum and``// minimum elements lies in the range [L, R]``int` `maxSubsetSum(vector<``int``> arr, ``int` `L, ``int` `R)``{``    ``int` `N = arr.size();` `    ``// Sort the given array arr[] in``    ``// non-decreasing order``    ``sort(arr.begin(), arr.end());` `    ``// Stores the sum of elements till``    ``// current index of the array arr[]``    ``int` `sum[N + 1] = {};` `    ``// Stores the Maximum subset sum``    ``int` `ans = 0;` `    ``// Create prefix sum array``    ``for` `(``int` `i = 1; i <= N; i++) {``        ``sum[i] = sum[i - 1] + arr[i - 1];``    ``}` `    ``// Iterate over all indices of array``    ``for` `(``int` `i = 0; i < N; i++) {` `        ``// Maximum possible value of``        ``// subset considering arr[i]``        ``// as the minimum element``        ``int` `val = arr[i] + R;` `        ``// Calculate the position of the``        ``// largest element <= val``        ``auto` `ptr = upper_bound(``            ``arr.begin(), arr.end(), val);``        ``ptr--;``        ``int` `j = ptr - arr.begin();` `        ``// If the difference between the``        ``// maximum and the minimum lies in``        ``// the range, update answer``        ``if` `((arr[j] - arr[i] <= R)``            ``&& (arr[j] - arr[i] >= L)) {``            ``ans = max(ans, sum[j + 1] - sum[i]);``        ``}``    ``}` `    ``// Return Answer``    ``return` `ans;``}` `// Driver Code``int` `main()``{``    ``vector<``int``> arr{ 6, 5, 0, 9, 1 };``    ``int` `L = 0;``    ``int` `R = 3;``    ``cout << maxSubsetSum(arr, L, R);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;` `class` `GFG{` `  ``static` `int` `upperBound(``int``[] a, ``int` `low, ``int` `high, ``int` `element){``    ``while``(low < high){``      ``int` `middle = low + (high - low)/``2``;``      ``if``(a[middle] > element)``        ``high = middle;``      ``else``        ``low = middle + ``1``;``    ``}``    ``return` `low;``  ``}` `  ``// Function to find Maximum Subset Sum such``  ``// that the difference between maximum and``  ``// minimum elements lies in the range [L, R]``  ``static` `int` `maxSubsetSum(``int``[] arr, ``int` `L, ``int` `R)``  ``{``    ``int` `N = arr.length;` `    ``// Sort the given array arr[] in``    ``// non-decreasing order``    ``Arrays.sort(arr);` `    ``// Stores the sum of elements till``    ``// current index of the array arr[]``    ``int` `[]sum  = ``new` `int``[N + ``1``];` `    ``// Stores the Maximum subset sum``    ``int` `ans = ``0``;` `    ``// Create prefix sum array``    ``for` `(``int` `i = ``1``; i <= N; i++) {``      ``sum[i] = sum[i - ``1``] + arr[i - ``1``];``    ``}` `    ``// Iterate over all indices of array``    ``for` `(``int` `i = ``0``; i < N; i++) {` `      ``// Maximum possible value of``      ``// subset considering arr[i]``      ``// as the minimum element``      ``int` `val = arr[i] + R;` `      ``// Calculate the position of the``      ``// largest element <= val``      ``int` `ptr = upperBound(arr, ``0``, N,val);``      ``ptr--;``      ``int` `j = ptr;` `      ``// If the difference between the``      ``// maximum and the minimum lies in``      ``// the range, update answer``      ``if` `((arr[j] - arr[i] <= R)``          ``&& (arr[j] - arr[i] >= L)) {``        ``ans = Math.max(ans, sum[j + ``1``] - sum[i]);``      ``}``    ``}` `    ``// Return Answer``    ``return` `ans;``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int``[] arr = { ``6``, ``5``, ``0``, ``9``, ``1` `};``    ``int` `L = ``0``;``    ``int` `R = ``3``;``    ``System.out.print(maxSubsetSum(arr, L, R));` `  ``}``}` `// This code is contributed by umadevi9616`

## Python3

 `# Python Program to implement``# the above approach``from` `functools ``import` `cmp_to_key` `def` `cmp_sort(a, b):``    ``return` `a ``-` `b` `def` `InsertionIndex(nums, target, left):``    ``low ``=` `0``    ``high ``=` `len``(nums)` `    ``while` `(low < high):``        ``mid ``=` `low ``+` `((high ``-` `low) ``/``/` `2``)` `        ``if` `(nums[mid] > target ``or` `(left ``and` `target ``=``=` `nums[mid])):``            ``high ``=` `mid``        ``else``:``            ``low ``=` `mid ``+` `1` `    ``return` `low` `def` `upper_bound(nums, target):``    ``targetRange ``=` `[``-``1``, ``-``1``]` `    ``leftIdx ``=` `InsertionIndex(nums, target, ``True``)` `    ``if` `(leftIdx ``=``=` `len``(nums) ``or` `nums[leftIdx] !``=` `target):``        ``return` `targetRange` `    ``targetRange[``0``] ``=` `leftIdx``    ``targetRange[``1``] ``=` `InsertionIndex(nums, target, ``False``) ``-` `1` `    ``return` `targetRange` `def` `maxSubsetSum(arr, L, R):``    ``N ``=` `len``(arr)` `    ``# Sort the given array arr[] in``    ``# non-decreasing order``    ``arr.sort(key ``=` `cmp_to_key(cmp_sort))` `    ``# Stores the sum of elements till``    ``# current index of the array arr[]``    ``sum` `=` `[``0` `for` `i ``in` `range``(N``+``1``)]` `    ``# Stores the Maximum subset sum``    ``ans ``=` `0` `    ``# Create prefix sum array``    ``for` `i ``in` `range``(``1``,N``+``1``):``        ``sum``[i] ``=` `sum``[i ``-` `1``] ``+` `arr[i ``-` `1``]``    ``# Iterate over all indices of array``    ``for` `i ``in` `range``(N):` `        ``# Maximum possible value of``        ``# subset considering arr[i]``        ``# as the minimum element``        ``val ``=` `arr[i] ``+` `R` `        ``# Calculate the position of the``        ``# largest element <= val``        ``ptr ``=` `upper_bound(arr, val)``        ``j ``=` `ptr[``1``]` `        ``# If the difference between the``        ``# maximum and the minimum lies in``        ``# the range, update answer``        ``if` `((arr[j] ``-` `arr[i] <``=` `R) ``and` `(arr[j] ``-` `arr[i] >``=` `L)):``            ``ans ``=` `max``(ans, ``sum``[j ``+` `1``] ``-` `sum``[i])` `    ``# Return Answer``    ``return` `ans` `# Driver Code``arr ``=` `[``6``, ``5``, ``0``, ``9``, ``1``]``L ``=` `0``R ``=` `3``print``(maxSubsetSum(arr, L, R))` `# This code is contributed by shinjanpatra`

## Javascript

 ``

Output:
`15`

Time Complexity: O(N*log N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up