Split Array Largest Sum
Problem Description
Given an integer array nums and an integer k, split nums into k non-empty contiguous subarrays such that the largest sum of any subarray is minimized.
Return the minimized largest sum of the split.
A subarray is a contiguous part of the array.
Examples
Example 1:Input: nums = [7,2,5,10,8], k = 2 Output: 18 Explanation: There are four ways to split nums into two subarrays. The best way is to split it into [7,2,5] and [10,8], where the largest sum among the two subarrays is only 18.
Input: nums = [1,2,3,4,5], k = 2 Output: 9 Explanation: There are four ways to split nums into two subarrays. The best way is to split it into [1,2,3] and [4,5], where the largest sum among the two subarrays is only 9.
Constraints
1 <= nums.length <= 10000 <= nums[i] <= 10⁶1 <= k <= min(50, nums.length)
Binary Search on Sum Space
The minimized largest sum must lie in the range [max(nums), sum(nums)].
If we split the array such that no subarray exceeds sum target, we can greedy pack the elements.
We run binary search on this sum range. Set left = max(nums) and right = sum(nums).
At each step, calculate the midpoint sum mid.
Determine if we can partition the array into at most k subarrays such that no subarray sum exceeds mid.
- If it is possible,
midis a valid partition limit. We record it as a candidate and attempt to find a smaller sum by searching the left half:right = mid - 1. - If it takes too many partitions,
midis too small, so we search the right half:left = mid + 1.
Solution 1: Binary Search on Subarray Sum
Perform binary search over possible maximum subarray sums, validating partition counts.
class Solution {
public int splitArray(int[] nums, int k) {
int left = 0;
int right = 0;
for (int num : nums) {
left = Math.max(left, num); // maximum single element sum
right += num; // sum of all elements
}
int result = right;
while (left <= right) {
int mid = left + (right - left) / 2;
if (canSplit(nums, mid, k)) {
result = mid; // record candidate
right = mid - 1; // try smaller sum limits
} else {
left = mid + 1; // try larger sum limits
}
}
return result;
}
private boolean canSplit(int[] nums, int maxSumLimit, int k) {
int subarrayCount = 1;
int currentSum = 0;
for (int num : nums) {
if (currentWeightPlusNumExceedsLimit(currentSum, num, maxSumLimit)) {
subarrayCount++;
currentSum = 0;
}
currentSum += num;
}
return subarrayCount <= k;
}
private boolean currentWeightPlusNumExceedsLimit(int sum, int val, int limit) {
return sum + val > limit;
}
}class Solution:
def splitArray(self, nums: list[int], k: int) -> int:
left = max(nums)
right = sum(nums)
result = right
def can_split(max_sum_limit: int) -> bool:
subarray_count = 1
current_sum = 0
for num in nums:
if current_sum + num > max_sum_limit:
subarray_count += 1
current_sum = 0
current_sum += num
return subarray_count <= k
while left <= right:
mid = left + (right - left) // 2
if can_split(mid):
result = mid # record candidate
right = mid - 1 # try smaller
else:
left = mid + 1 # try larger
return result#include <vector>
#include <numeric>
#include <algorithm>
class Solution {
private:
bool canSplit(const std::vector<int>& nums, int maxSumLimit, int k) {
int subarrayCount = 1;
int currentSum = 0;
for (int num : nums) {
if (currentSum + num > maxSumLimit) {
subarrayCount++;
currentSum = 0;
}
currentSum += num;
}
return subarrayCount <= k;
}
public:
int splitArray(std::vector<int>& nums, int k) {
int left = *std::max_element(nums.begin(), nums.end());
int right = std::accumulate(nums.begin(), nums.end(), 0);
int result = right;
while (left <= right) {
int mid = left + (right - left) / 2;
if (canSplit(nums, mid, k)) {
result = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return result;
}
};Complexity Analysis
- Time Complexity: O(n log m) where n is the number of elements in the array and m is the sum of all elements. The binary search runs in log m steps, and each validation pass takes O(n) time.
- Space Complexity: O(1) auxiliary space as we track boundaries using simple variables.
Where It Breaks
This solution depends on the subarrays being contiguous. If we can group elements non-contiguously, this greedy partition check fails, and the problem becomes NP-hard.
Common Mistakes
- Incorrect lower bound: Initializing
leftto0or1instead ofmax(nums). If the maximum sum limit is smaller than a single element, the element can never fit in any partition, violating the model boundaries. - Off-by-one errors on partition count: Initializing the count of subarrays to
0instead of1.
Frequently Asked Questions
How does this differ from the Book Allocation Problem?
It is mathematically identical. Both problems ask to partition a sorted/unsorted array of values into k groups such that the maximum group sum is minimized.
What happens if k equals the array length?
The binary search will converge to max(nums), since each element forms its own subarray.