Open In App

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

Last Updated : 07 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • 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++




#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";
}


C




#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);
}


Java




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");
    }
}


Python3




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


C#




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


Javascript




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

  • 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++




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




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


Python3




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




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


Javascript




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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads