Maximum subset sum having difference between its maximum and minimum in range [L, R]
Last Updated : 15 Feb, 2023
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 <bits/stdc++.h> 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
C# // C# program for the above approach using System; 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 Array.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 static void Main(string[] args) { int[] arr = { 6, 5, 0, 9, 1 }; int L = 0; int R = 3; Console.WriteLine(maxSubsetSum(arr, L, R)); } } // This code is contributed by phasing17
JavaScript <script> // JavaScript Program to implement // the above approach function InsertionIndex(nums, target, left) { let low = 0, high = nums.length while (low < high) { const mid = low + Math.floor((high - low) / 2) if (nums[mid] > target || (left && target === nums[mid])) high = mid else low = mid + 1 } return low } function upper_bound(nums, target) { const targetRange = [-1, -1] const leftIdx = InsertionIndex(nums, target, true) if (leftIdx === nums.length || nums[leftIdx] != target) return targetRange targetRange[0] = leftIdx targetRange[1] = InsertionIndex(nums, target, false) - 1 return targetRange } function maxSubsetSum(arr, L, R) { let N = arr.length; // Sort the given array arr[] in // non-decreasing order arr.sort(function (a, b) { return a - b }) // Stores the sum of elements till // current index of the array arr[] let sum = new Array(N + 1).fill(0); // Stores the Maximum subset sum let ans = 0; // Create prefix sum array for (let i = 1; i <= N; i++) { sum[i] = sum[i - 1] + arr[i - 1]; } // Iterate over all indices of array for (let i = 0; i < N; i++) { // Maximum possible value of // subset considering arr[i] // as the minimum element let val = arr[i] + R; // Calculate the position of the // largest element <= val let ptr = upper_bound( arr, val); let j = ptr[1] // 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 let arr = [6, 5, 0, 9, 1]; let L = 0; let R = 3; document.write(maxSubsetSum(arr, L, R)); // This code is contributed by Potta Lokesh </script>
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Similar Reads
Split array into subarrays such that sum of difference between their maximums and minimums is maximum Given an array arr[] consisting of N integers, the task is to split the array into subarrays such that the sum of the difference between the maximum and minimum elements for all the subarrays is maximum. Examples : Input: arr[] = {8, 1, 7, 9, 2}Output: 14Explanation:Consider splitting the given arra
6 min read
Minimize difference between maximum and minimum Subarray sum by splitting Array into 4 parts Given an array arr[] of size N, the task is to find the minimum difference between the maximum and the minimum subarray sum when the given array is divided into 4 non-empty subarrays. Examples: Input: N = 5, arr[] = {3, 2, 4, 1, 2}Output: 2Explanation: Divide the array into four parts as {3}, {2}, {
14 min read
Split array into K Subarrays to minimize sum of difference between min and max Given a sorted array arr[] of size N and integer K, the task is to split the array into K non-empty subarrays such that the sum of the difference between the maximum element and the minimum element of each subarray is minimized. Note: Every element of the array must be included in one subarray and e
6 min read
Count of subsequences with a sum in range [L, R] and difference between max and min element at least X Given an array arr[] consisting of N positive integers and 3 integers L, R, and X, the task is to find the number of subsequences of size atleast 2 with a sum in the range [L, R], and the difference between the maximum and minimum element is at least X. (Nâ¤15) Examples: Input: arr[] = {1 2 3}, L = 5
9 min read
Find sum of difference of maximum and minimum over all possible subsets of size K Given an array arr[] of N integers and an integer K, the task is to find the sum of the difference between the maximum and minimum elements over all possible subsets of size K. Examples: Input: arr[] = {1, 1, 3, 4}, K = 2Output: 11Explanation:There are 6 subsets of the given array of size K(= 2). Th
12 min read