Open In App

Split into K subarrays to minimize the maximum sum of all subarrays

Last Updated : 06 Jan, 2025
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

Given an array arr[] and a number k, split the given array into k subarrays such that the maximum subarray sum achievable out of k subarrays formed is the minimum possible. The task is to find that possible subarray sum.

Examples:

Input: arr[] = [1, 2, 3, 4], k = 3 
Output:
Explanation: Optimal Split is [1, 2], [3], [4]. Maximum sum of all subarrays is 4, which is minimum possible for 3 splits.

Input: arr[] = [1, 1, 2], k = 2 
Output:
Explanation: Splitting the array as [1, 1] and [2] is optimal. This results is a maximum sum subarray of 2.

[Naive Approach] – By iterating through every possible solution – O(nCk) Time and O(k) Space

To explore all possibilities, we use backtracking. At each step, the array is divided into subarrays, and the sum of each subarray is calculated.

C++
// C++ code to iterate through
// every possible solution
#include <bits/stdc++.h>
using namespace std;
void solve(vector<int> &arr, int k, int index, int maxsum, int &ans) {

    // K = 1 is the base Case
    int n = arr.size();
    int sum = 0;
    if (k == 1) {

        for (int i = index; i < n; i++) {

            sum += arr[i];
        }
      
        // we update maxsum
        maxsum = max(maxsum, sum);

        ans = min(ans, maxsum);
        return;
    }

    // using for loop to divide the array into K-subarray
    for (int i = index; i < n; i++) {

        sum += arr[i];
      
        // for each subarray we calculate sum ans update
        // maxsum
        maxsum = max(maxsum, sum);

        solve(arr, k - 1, i + 1, maxsum, ans);
    }
}

int splitArray(vector<int> &arr, int k) {

    int ans = INT_MAX;
    solve(arr, k, 0, 0, ans);
    return ans;
}
int main() {

    vector<int> arr = {1, 2, 3, 4};
    int k = 3;

    cout << splitArray(arr, k);
}
Java Python C# JavaScript

Output
4

Time Complexity: O((n-1)C(k-1))
(Note: ‘c’ here depicts combinations i.e. ((n-1)!/((n-k)!*(k-1)!), where n is the number of elements of the array and k is the number of divisions.
Auxiliary Space: O(k)

[Expected Approach] – Using Binary Search – O(n*log(sum)) Time and O(1) Space

The approach uses Binary Search to find the minimum possible value for the maximum subarray sum when the array is split into k subarrays. The binary search range is between the maximum element of the array (since no subarray can have a sum less than the largest element) and the total sum of the array (which is the maximum sum when the entire array is considered as a single subarray). For each midpoint value, we check if it’s possible to split the array into k or fewer subarrays such that no subarray’s sum exceeds the midpoint. If it is possible, we attempt to minimize the maximum sum by narrowing the search range to smaller values.

C++
// C++ code to solve above problem
// using binary search
#include <bits/stdc++.h>
using namespace std;
bool check(int mid, vector<int> &arr, int k) {

    int n = arr.size();
    int count = 0;
    int sum = 0;
    for (int i = 0; i < n; i++) {

        // If individual element is greater
        // maximum possible sum
        if (arr[i] > mid)
            return false;

        // Increase sum of current sub - arr
        sum += arr[i];

        // If the sum is greater than
        // mid increase count
        if (sum > mid) {

            count++;
            sum = arr[i];
        }
    }
    count++;

    if (count <= k)
        return true;
    return false;
}

int splitArray(vector<int> &arr, int k) {

    int n = arr.size();
    int max = *max_element(arr.begin(), arr.end());

    // Max subarr sum, considering subarr of length 1
    int start = max;

    // Max subarr sum, considering subarr of length n
    int end = 0;

    for (int i = 0; i < n; i++) {

        end += arr[i];
    }

    // ans stores possible
    // maximum sub arr sum
    int ans = 0;
    while (start <= end) {

        int mid = (start + end) / 2;

        // If mid is possible solution
        // Put ans = mid;
        if (check(mid, arr, k)) {

            ans = mid;
            end = mid - 1;
        }
        else {
            start = mid + 1;
        }
    }

    return ans;
}

int main() {

    vector<int> arr = {1, 2, 3, 4};
    int k = 3;
    cout << splitArray(arr, k);
}
Java Python C# JavaScript

Output
4


Next Article

Similar Reads

three90RightbarBannerImg