Split the given array into K sub-arrays such that maximum sum of all sub arrays is minimum - GeeksforGeeks

30 Mar, 2022
Given an Array[] of N elements and a number K. ( 1 <= K <= N ) . Split the given array into K subarrays (they must cover all the elements). The maximum subarray sum achievable out of K subarrays formed, must be the minimum possible. Find that possible subarray sum.Examples:
Input : Array[] = {1, 2, 3, 4}, K = 3 Output : 4 Optimal Split is {1, 2}, {3}, {4} . Maximum sum of all subarrays is 4, which is minimum possible for 3 splits.Input : Array[] = {1, 1, 2} K = 2 Output : 2 
Naive approach:
Idea is to find out all the possibilities.
To find out all possibilities we use BACKTRACKING.
At each step, we divide the array into sub-array and find the sum of the sub-array and update the maximum sum
Below is the implementation of the above approach:
C++
C
Java
Python3
C#
Javascript
#include <bits/stdc++.h>using namespace std;int ans = 100000000;// the answer is stored in ans// we call this function solvevoid solve(int a[], int n, int k, int index, int sum,           int maxsum){    // K=1 is the base Case    if (k == 1) {        maxsum = max(maxsum, sum);        sum = 0;        for (int i = index; i < n; i++) {            sum += a[i];        }        // we update maxsum        maxsum = max(maxsum, sum);        // the answer is stored in ans        ans = min(ans, maxsum);        return;    }    sum = 0;    // using for loop to divide the array into K-subarray    for (int i = index; i < n; i++) {        sum += a[i];        // for each subarray we calculate sum ans update        // maxsum        maxsum = max(maxsum, sum);        // calling function again        solve(a, n, k - 1, i + 1, sum, maxsum);    }}// Driver Codeint main(){    int arr[] = { 1, 2, 3, 4 };    int k = 3; // K divisions    int n = 4; // Size of Array    solve(arr, n, k, 0, 0, 0);    cout << ans << "\n";}
#include <stdio.h>int ans = 100000000;// the answer is stored in ans// we call this function solve// max function is used to find max of two elementsint max(int a, int b) { return a > b ? a : b; }// min function is used to find min of two elementsint min(int a, int b) { return a < b ? a : b; }void solve(int a[], int n, int k, int index, int sum,           int maxsum){    // K=1 is the base Case    if (k == 1) {        maxsum = max(maxsum, sum);        sum = 0;        for (int i = index; i < n; i++) {            sum += a[i];        }        // we update maxsum        maxsum = max(maxsum, sum);        // the answer is stored in ans        ans = min(ans, maxsum);        return;    }    sum = 0;    // using for loop to divide the array into K-subarray    for (int i = index; i < n; i++) {        sum += a[i];        // for each subarray we calculate sum ans update        // maxsum        maxsum = max(maxsum, sum);        // calling function again        solve(a, n, k - 1, i + 1, sum, maxsum);    }}// Driver Codeint main(){    int arr[] = { 1, 2, 3, 4 };    int k = 3; // K divisions    int n = 4; // Size of Array    solve(arr, n, k, 0, 0, 0);    printf("%d", ans);}
class GFG {    public static int ans = 10000000;    public static void solve(int a[], int n, int k,                             int index, int sum, int maxsum)    {        // K=1 is the base Case        if (k == 1) {            maxsum = Math.max(maxsum, sum);            sum = 0;            for (int i = index; i < n; i++) {                sum += a[i];            }            // we update maxsum            maxsum = Math.max(maxsum, sum);            // the answer is stored in ans            ans = Math.min(ans, maxsum);            return;        }        sum = 0;        // using for loop to divide the array into        // K-subarray        for (int i = index; i < n; i++) {            sum += a[i];            // for each subarray we calculate sum ans update            // maxsum            maxsum = Math.max(maxsum, sum);            // calling function again            solve(a, n, k - 1, i + 1, sum, maxsum);        }    }    public static void main(String[] args)    {        int arr[] = { 1, 2, 3, 4 };        int k = 3; // K divisions        int n = 4; // Size of Array        solve(arr, n, k, 0, 0, 0);        System.out.println(ans + "\n");    }}
ans = 10000000 def solve(a, n, k, index, sum, maxsum):    global ans         # K=1 is the base Case    if (k == 1):        maxsum = max(maxsum, sum)        sum = 0        for i in range(index,n):            sum += a[i]         # we update maxsum        maxsum = max(maxsum, sum)                 # the answer is stored in ans        ans = min(ans, maxsum)        return     sum = 0         # using for loop to divide the array into    # K-subarray    for i in range(index, n):        sum += a[i]                 # for each subarray we calculate sum ans update        # maxsum        maxsum = max(maxsum, sum)                 # calling function again        solve(a, n, k - 1, i + 1, sum, maxsum)     # driver code     arr = [ 1, 2, 3, 4 ]k = 3 # K divisionsn = 4 # Size of Arraysolve(arr, n, k, 0, 0, 0)print(ans)     # this code is contributed by shinjanpatra
using System;class GFG {    public static int ans = 10000000;    public static void solve(int []a, int n, int k,                            int index, int sum, int maxsum)    {               // K=1 is the base Case        if (k == 1) {            maxsum = Math.Max(maxsum, sum);            sum = 0;            for (int i = index; i < n; i++) {                sum += a[i];            }                       // we update maxsum            maxsum = Math.Max(maxsum, sum);                       // the answer is stored in ans            ans = Math.Min(ans, maxsum);            return;        }        sum = 0;               // using for loop to divide the array into        // K-subarray        for (int i = index; i < n; i++) {            sum += a[i];                       // for each subarray we calculate sum ans update            // maxsum            maxsum = Math.Max(maxsum, sum);                       // calling function again            solve(a, n, k - 1, i + 1, sum, maxsum);        }    }     // Driver code    public static void Main(String[] args)    {        int []arr = { 1, 2, 3, 4 };        int k = 3; // K divisions        int n = 4; // Size of Array        solve(arr, n, k, 0, 0, 0);        Console.Write(ans + "\n");    }} // This code is contributed by shivanisinghss2110
<script>var ans = 10000000; function solve(a, n, k, index, sum, maxsum)    {        // K=1 is the base Case        if (k == 1) {            maxsum = Math.max(maxsum, sum);            sum = 0;            for (var i = index; i < n; i++) {                sum += a[i];            }            // we update maxsum            maxsum = Math.max(maxsum, sum);            // the answer is stored in ans            ans = Math.min(ans, maxsum);            return;        }        sum = 0;                 // using for loop to divide the array into        // K-subarray        for (var i = index; i < n; i++) {            sum += a[i];                         // for each subarray we calculate sum ans update            // maxsum            maxsum = Math.max(maxsum, sum);                         // calling function again            solve(a, n, k - 1, i + 1, sum, maxsum);        }    }             var arr = [ 1, 2, 3, 4 ];        var k = 3; // K divisions        var n = 4; // Size of Array        solve(arr, n, k, 0, 0, 0);        document.write(ans + "\n");                 // this code is contributed by shivanisinghss2110</script>
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.
Efficient Approach : 
Idea is to use Binary Search to find an optimal solution.
For binary search minimum sum can be 1 and the maximum sum can be the sum of all the elements.
To check if mid is the maximum subarray sum possible. Maintain a count of sub-arrays, include all possible elements in subarray until their sum is less than mid. After this evaluation, if the count is less than or equal to K, then mid is achievable else not. (Since if the count is less than K, we can further divide any subarray its sum will never increase mid ).
Find the minimum possible value of mid which satisfies the condition.
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ implementation of the above approach#include <bits/stdc++.h>using namespace std; // Function to check if mid can// be maximum sub - arrays sumbool check(int mid, int array[], int n, int K){    int count = 0;    int sum = 0;    for (int i = 0; i < n; i++) {         // If individual element is greater        // maximum possible sum        if (array[i] > mid)            return false;         // Increase sum of current sub - array        sum += array[i];         // If the sum is greater than        // mid increase count        if (sum > mid) {            count++;            sum = array[i];        }    }    count++;     // Check condition    if (count <= K)        return true;    return false;} // Function to find maximum subarray sum// which is minimumint solve(int array[], int n, int K){    int* max = max_element(array, array + n);    int start = *max; //Max subarray sum, considering subarray of length 1    int end = 0;     for (int i = 0; i < n; i++) {        end += array[i]; //Max subarray sum, considering subarray of length n    }     // Answer stores possible    // maximum sub array sum    int answer = 0;    while (start <= end) {        int mid = (start + end) / 2;         // If mid is possible solution        // Put answer = mid;        if (check(mid, array, n, K)) {            answer = mid;            end = mid - 1;        }        else {            start = mid + 1;        }    }     return answer;} // Driver Codeint main(){    int array[] = { 1, 2, 3, 4 };    int n = sizeof(array) / sizeof(array[0]);    int K = 3;    cout << solve(array, n, K);}
// Java implementation of the above approachclass GFG {     // Function to check if mid can    // be maximum sub - arrays sum    static boolean check(int mid, int array[], int n, int K)    {         int count = 0;        int sum = 0;        for (int i = 0; i < n; i++) {             // If individual element is greater            // maximum possible sum            if (array[i] > mid)                return false;             // Increase sum of current sub - array            sum += array[i];             // If the sum is greater than            // mid increase count            if (sum > mid) {                count++;                sum = array[i];            }        }        count++;         // Check condition        if (count <= K)            return true;        return false;    }     // Function to find maximum subarray sum    // which is minimum    static int solve(int array[], int n, int K)    {        int start = 1;        for (int i = 0; i < n; ++i) {            if (array[i] > start)                start = array[i]; //Max subarray sum, considering subarray of length 1        }        int end = 0;         for (int i = 0; i < n; i++) {            end += array[i]; //Max subarray sum, considering subarray of length n        }         // Answer stores possible        // maximum sub array sum        int answer = 0;        while (start <= end) {            int mid = (start + end) / 2;             // If mid is possible solution            // Put answer = mid;            if (check(mid, array, n, K)) {                answer = mid;                end = mid - 1;            }            else {                start = mid + 1;            }        }         return answer;    }     // Driver Code    public static void main(String[] args)    {        int array[] = { 1, 2, 3, 4 };        int n = array.length;        int K = 3;        System.out.println(solve(array, n, K));    }} // This code is contributed by AnkitRai01
# Python 3 implementation of the above approach # Function to check if mid can# be maximum sub - arrays sumdef check(mid, array, n, K):    count = 0    sum = 0    for i in range(n):                 # If individual element is greater        # maximum possible sum        if (array[i] > mid):            return False         # Increase sum of current sub - array        sum += array[i]         # If the sum is greater than        # mid increase count        if (sum > mid):            count += 1            sum = array[i]    count += 1     # Check condition    if (count <= K):        return True    return False # Function to find maximum subarray sum# which is minimumdef solve(array, n, K):       start = max(array) #Max subarray sum, considering subarray of length 1    end = 0     for i in range(n):        end += array[i] #Max subarray sum, considering subarray of length n     # Answer stores possible    # maximum sub array sum    answer = 0    while (start <= end):        mid = (start + end) // 2         # If mid is possible solution        # Put answer = mid;        if (check(mid, array, n, K)):            answer = mid            end = mid - 1        else:            start = mid + 1     return answer # Driver Codeif __name__ == '__main__':    array = [1, 2, 3, 4]    n = len(array)    K = 3    print(solve(array, n, K))     # This code is contributed by# Surendra_Gangwar
// C# implementation of the above approachusing System;     class GFG{         // Function to check if mid can    // be maximum sub - arrays sum    static Boolean check(int mid, int []array,                                int n, int K)    {                 int count = 0;        int sum = 0;        for (int i = 0; i < n; i++)        {                 // If individual element is greater            // maximum possible sum            if (array[i] > mid)                return false;                 // Increase sum of current sub - array            sum += array[i];                 // If the sum is greater than            // mid increase count            if (sum > mid)            {                count++;                sum = array[i];            }        }        count++;             // Check condition        if (count <= K)            return true;        return false;    }         // Function to find maximum subarray sum    // which is minimum    static int solve(int []array, int n, int K)    {        int start = 1;        for (int i = 0; i < n; ++i) {            if (array[i] > start)                start = array[i]; //Max subarray sum, considering subarray of length 1        }        int end = 0;             for (int i = 0; i < n; i++)        {            end += array[i];  //Max subarray sum, considering subarray of length n        }             // Answer stores possible        // maximum sub array sum        int answer = 0;        while (start <= end)        {            int mid = (start + end) / 2;                 // If mid is possible solution            // Put answer = mid;            if (check(mid, array, n, K))            {                answer = mid;                end = mid - 1;            }            else            {                start = mid + 1;            }        }             return answer;    }         // Driver Code    public static void Main (String[] args)    {        int []array = { 1, 2, 3, 4 };        int n = array.Length ;        int K = 3;        Console.WriteLine(solve(array, n, K));    }} // This code is contributed by Princi Singh
<script>// Javascript implementation of the above approach // Function to check if mid can// be maximum sub - arrays sumfunction check(mid, array, n, K){    var count = 0;    var sum = 0;    for (var i = 0; i < n; i++) {         // If individual element is greater        // maximum possible sum        if (array[i] > mid)            return false;         // Increase sum of current sub - array        sum += array[i];         // If the sum is greater than        // mid increase count        if (sum > mid) {            count++;            sum = array[i];        }    }    count++;     // Check condition    if (count <= K)        return true;    return false;} // Function to find maximum subarray sum// which is minimumfunction solve(array, n, K){    var max = array.reduce((a,b)=>Math.max(a,b));    var start = max; //Max subarray sum, considering subarray of length 1    var end = 0;     for (var i = 0; i < n; i++) {        end += array[i]; //Max subarray sum, considering subarray of length n    }     // Answer stores possible    // maximum sub array sum    var answer = 0;    while (start <= end) {        var mid = parseInt((start + end) / 2);         // If mid is possible solution        // Put answer = mid;        if (check(mid, array, n, K)) {            answer = mid;            end = mid - 1;        }        else {            start = mid + 1;        }    }     return answer;} // Driver Codevar array = [1, 2, 3, 4];var n = array.length;var K = 3;document.write( solve(array, n, K)); </script>
4
Time Complexity : O(N*log(Sum)) Where N is the number of elements of the array and Sum is the sum of all the elements of the array.
ankthon
princi singh
SURENDRA_GANGWAR
avinashraghuthu
pavang2001
noob2000
gulshankumarar231
RishMeh19
aditya1762002
saurabh1990aror
shivanisinghss2110
kk773572498
shinjanpatra
Binary Search
subarray
Arrays
Greedy
Searching
Arrays
Searching
Greedy
Binary Search
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Stack Data Structure (Introduction and Program)
Introduction to Arrays
Multidimensional Arrays in Java
Dijkstra's shortest path algorithm | Greedy Algo-7
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Write a program to print all permutations of a given string
Huffman Coding | Greedy Algo-3