Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to partition an array of integers in a way that minimizes the maximum of the sum of each partition?

The inputs are an array A of positive or null integers and another integer K.

We should partition A into K blocks of consecutive elements (by "partition" I mean that every element of A belongs to some block and 2 different blocks don't contain any element in common).

We define the sum of a block as sum of the elements of the block.

The goal is to find such a partition in K blocks such that the maximum of the sums of each block (let's call that "MaxSumBlock") is minimized.

We need to output the MaxSumBlock (we don't need to find an actual partition)

Here is an example:

Input:

A = {2, 1, 5, 1, 2, 2, 2}
K = 3

Expected output:

MaxSumBlock: 6
(with partition: {2, 1}, {5, 1}, {2, 2, 2})

In the expected output, the sums of each block are 3, 6 and 6. The max is 6.

Here is an non optimal partition:

partition: {2, 1}, {5}, {1, 2, 2, 2}

The sums of each block in that case are 3, 6 and 7. The max is hence 7. It is not a correct answer.

What algorithm solves this problem?

EDIT: K and the size of A is no bigger than 100'000. Each element of A is no bigger than 10'000

like image 898
Brainless Avatar asked Sep 07 '15 11:09

Brainless


People also ask

How do you divide an array into two parts with minimal differences?

To partition nums , put each element of nums into one of the two arrays. Return the minimum possible absolute difference. Input: nums = [3,9,7,3] Output: 2 Explanation: One optimal partition is: [3,9] and [7,3]. The absolute difference between the sums of the arrays is abs((3 + 9) - (7 + 3)) = 2.

How do I split an array into two arrays with almost equal sum?

The algorithm to divide an array into 2 parts of approximately equal sum is as follows: Initialize 2 empty sets to hold our answer. Sort the array in reverse order. While maintaining the sum of the 2 sets, iterate over all the elements from array and append them into the set which has the lesser sum.


1 Answers

Use binary search.

Let max sum range from 0 to sum(array). So, mid = (range / 2). See if mid can be achieved by partitioning into k sets in O(n) time. If yes, go for lower range and if not, go for a higher range.

This will give you the result in O(n log n).

PS: if you have any problem with writing the code, I can help but I'd suggest you try it first yourself.

EDIT:
as requested, I'll explain how to find if mid can be achieved by partitioning into k sets in O(n) time.
Iterate through the elements till sum is less than or equal to mid. As soon as it gets greater than mid, let it be part of next set. If you get k or less sets, mid is achievable, else not.

like image 86
vish4071 Avatar answered Nov 11 '22 21:11

vish4071