Open In App

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

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 :
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 :



Recommended Practice

Naive approach:

Below is the implementation of the above approach:






#include <bits/stdc++.h>
using namespace std;
int ans = 100000000;
// the answer is stored in ans
// we call this function solve
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 Code
int 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 elements
int max(int a, int b) { return a > b ? a : b; }
// min function is used to find min of two elements
int 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 Code
int 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 divisions
n = 4 # Size of Array
solve(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>

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.

Space Complexity: O(K)

Efficient Approach : 

Below is the implementation of the above approach: 




// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to check if mid can
// be maximum sub - arrays sum
bool 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
int 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 Code
int 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 approach
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;
        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 sum
def 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 minimum
def 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 Code
if __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 approach
using 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 sum
function 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 minimum
function 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 Code
var array = [1, 2, 3, 4];
var n = array.length;
var K = 3;
document.write( solve(array, n, K));
  
</script>

Output
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.
Auxiliary Space: O(1) as no extra space has been used.


Article Tags :