Open In App

Maximize the Sum of Minimum in each Group of size K

Last Updated : 26 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array nums[] of size N and a positive integer K, divide the elements of the array into N/K groups, each of size K such that the sum of the smallest elements in each group is maximized.

Examples:

Input: nums = {1,4,3,2}, K = 2
Output: 4
Explanation: All possible groupings (ignoring the ordering of elements) are:

  • (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3
  • (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3
  • (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4

So the maximum possible sum is 4.

Input: nums = {6,5,1,2}, K = 2
Output: 6
Explanation: All possible groupings (ignoring the ordering of elements) are:

  • (6, 5), (1, 2) = min(6, 5) + min(1, 2) = 5 + 1 = 6
  • (6, 1), (5, 2) = min(6, 1) + min(5, 2) = 1 + 2 = 3
  • (6, 2), (5, 1) = min(6, 2) + min(5, 1) = 2 + 1 = 3

So the maximum possible sum is 6.

Approach: The above problem can be solved using the following approach:

Sort the array in ascending order to bring smaller elements together. Then, group each K elements from the beginning to end. And first element of each group will be the smallest element that we need to sum into our result. When we sort the array in ascending order, the smallest elements will be at the beginning of the sorted array. By creating groups from the sorted array, we are effectively grouping the smallest values together, which maximizes the sum of their minimums. If the array is not sorted, we might end up with groups that have larger elements in the minimum position, reducing the overall sum of minimum elements.

Steps to solve the problem:

  • Sort the array in ascending order to bring smallest elements at the start of the array.
  • Iterate through the sorted array, skipping K elements each time.
    • Sum the minimum of each group into a result variable.
  • Finally, return the result.

Below is the implementation of the above approach:

C++
// C++ Code for the above approach:

#include <bits/stdc++.h>
using namespace std;

int maximizeSum(vector<int>& nums, int K)
{
    int n = nums.size();
    // Sort the array in ascending order to
    // group the smallest elements together
    sort(nums.begin(), nums.end());

    int result = 0;

    // Iterate through the sorted array,
    // skipping K elements each time to get
    // the smallest element in each group
    for (int i = 0; i < n; i += K)
        result += nums[i];

    return result;
}

// Driver code
int main()
{
    vector<int> nums = { 6, 5, 1, 2 };
    // Each group size
    int K = 2;

    // Display the result.
    cout << maximizeSum(nums, K) << endl;

    return 0;
}
Java
import java.util.Arrays;

class Main {
    public static int maximizeSum(int[] nums, int K)
    {
        int n = nums.length;

        // Sort the array in ascending order to
        // group the smallest elements together
        Arrays.sort(nums);

        int result = 0;

        // Iterate through the sorted array,
        // skipping K elements each time to get
        // the smallest element in each group
        for (int i = 0; i < n; i += K)
            result += nums[i];

        return result;
    }

    public static void main(String[] args)
    {
        int[] nums = { 6, 5, 1, 2 };
        // Each group size
        int K = 2;

        // Display the result.
        System.out.println(maximizeSum(nums, K));
    }
}
Python3
def maximize_sum(nums, K):
    n = len(nums)
    # Sort the array in ascending order to
    # group the smallest elements together
    nums.sort()

    result = 0

    # Iterate through the sorted array,
    # skipping K elements each time to get
    # the smallest element in each group
    for i in range(0, n, K):
        result += nums[i]

    return result


# Driver code
if __name__ == "__main__":
    nums = [6, 5, 1, 2]
    # Each group size
    K = 2

    # Display the result.
    print(maximize_sum(nums, K))
C#
using System;
using System.Linq;

class Program
{
    static int MaximizeSum(int[] nums, int K)
    {
        int n = nums.Length;
        
        // Sort the array in ascending order to
        // group the smallest elements together
        Array.Sort(nums);

        int result = 0;

        // Iterate through the sorted array,
        // skipping K elements each time to get
        // the smallest element in each group
        for (int i = 0; i < n; i += K)
        {
            result += nums[i];
        }

        return result;
    }

    static void Main()
    {
        int[] nums = { 6, 5, 1, 2 };
        // Each group size
        int K = 2;

        // Display the result.
        Console.WriteLine(MaximizeSum(nums, K));
    }
}
Javascript
function MaximizeSum(nums, K) {
    nums.sort((a, b) => a - b); // Sort the array in ascending order
    
    let result = 0;
    const n = nums.length;

    // Iterate through the sorted array,
    // skipping K elements each time to get
    // the smallest element in each group
    for (let i = 0; i < n; i += K) {
        result += nums[i];
    }

    return result;
}

// Test case
const nums = [6, 5, 1, 2];
const K = 2; // Each group size

// Display the result
console.log(MaximizeSum(nums, K));

Output
6




Time Complexity: O(N*log(N)), where N is the size of input array nums[]
Auxiliary Space: O(1)

Approach 2: Using Min Heap

  • Initialize an empty min heap.
  • Push the elements of the array nums[] into min heap.
  • Pop the smallest K elements from min heap.
  • Sum these popped elements and return the result.

Example :

C++
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

int maxSumOfMin(const vector<int>& nums, int K) {
    priority_queue<int, vector<int>, greater<int>> minHeap;
    int result = 0;

    // Push the elements of nums[] into min heap
    for (int num : nums) {
        minHeap.push(num);
    }

    // Pop the smallest K elements from min heap
    for (int i = 0; i < K; i++) {
        result += minHeap.top();
        minHeap.pop();
    }

    return result;
}

int main() {
    vector<int> nums1 = {1, 4, 3, 2};
    int K1 = 2;
    cout << maxSumOfMin(nums1, K1) << endl;

    vector<int> nums2 = {6, 5, 1, 2};
    int K2 = 2;
    cout << maxSumOfMin(nums2, K2) << endl;

    return 0;
}
Java
import java.util.PriorityQueue;

public class MaxSumOfMin {

    public static int maxSumOfMin(int[] nums, int K) {
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        int result = 0;

        // Push the elements of nums[] into min heap
        for (int num : nums) {
            minHeap.add(num);
        }

        // Pop the smallest K elements from min heap
        for (int i = 0; i < K; i++) {
            result += minHeap.poll();
        }

        return result;
    }

    public static void main(String[] args) {
        int[] nums1 = {1, 4, 3, 2};
        int K1 = 2;
        System.out.println(maxSumOfMin(nums1, K1));

        int[] nums2 = {6, 5, 1, 2};
        int K2 = 2;
        System.out.println(maxSumOfMin(nums2, K2));
    }
}
Python
import heapq

def maxSumOfMin(nums, K):
    min_heap = []
    result = 0    
    # Push the elements of nums[] into min heap
    for num in nums:
        heapq.heappush(min_heap, num)  
    # Pop the smallest K elements from min heap
    for _ in range(K):
        result += heapq.heappop(min_heap)  
    return result
# Example usage:
nums1 = [1, 4, 3, 2]
K1 = 2
print(maxSumOfMin(nums1, K1))
nums2 = [6, 5, 1, 2]
K2 = 2
print(maxSumOfMin(nums2, K2))
JavaScript
class MinHeap {
    constructor() {
        this.heap = [];
    }

    push(val) {
        this.heap.push(val);
        this.heapifyUp(this.heap.length - 1);
    }

    pop() {
        if (this.heap.length === 0) return null;
        if (this.heap.length === 1) return this.heap.pop();
        
        const top = this.heap[0];
        this.heap[0] = this.heap.pop();
        this.heapifyDown(0);
        return top;
    }

    heapifyUp(index) {
        let currentIndex = index;
        while (currentIndex > 0) {
            const parentIndex = Math.floor((currentIndex - 1) / 2);
            if (this.heap[currentIndex] < this.heap[parentIndex]) {
                [this.heap[currentIndex], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[currentIndex]];
                currentIndex = parentIndex;
            } else {
                break;
            }
        }
    }

    heapifyDown(index) {
        let currentIndex = index;
        const length = this.heap.length;
        while (true) {
            let leftChildIndex = 2 * currentIndex + 1;
            let rightChildIndex = 2 * currentIndex + 2;
            let smallest = currentIndex;
            if (leftChildIndex < length && this.heap[leftChildIndex] < this.heap[smallest]) {
                smallest = leftChildIndex;
            }
            if (rightChildIndex < length && this.heap[rightChildIndex] < this.heap[smallest]) {
                smallest = rightChildIndex;
            }
            if (smallest !== currentIndex) {
                [this.heap[currentIndex], this.heap[smallest]] = [this.heap[smallest], this.heap[currentIndex]];
                currentIndex = smallest;
            } else {
                break;
            }
        }
    }
}

function maxSumOfMin(nums, K) {
    const minHeap = new MinHeap();
    let result = 0;

    // Push the elements of nums[] into min heap
    for (const num of nums) {
        minHeap.push(num);
    }

    // Pop the smallest K elements from min heap
    for (let i = 0; i < K; i++) {
        result += minHeap.pop();
    }

    return result;
}

// Example usage:
const nums1 = [1, 4, 3, 2];
const K1 = 2;
console.log(maxSumOfMin(nums1, K1));

const nums2 = [6, 5, 1, 2];
const K2 = 2;
console.log(maxSumOfMin(nums2, K2));

output :

3
3


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads