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++
#include <bits/stdc++.h>
using namespace std;
int ans = 100000000;
void solve( int a[], int n, int k, int index, int sum,
int maxsum)
{
if (k == 1) {
maxsum = max(maxsum, sum);
sum = 0;
for ( int i = index; i < n; i++) {
sum += a[i];
}
maxsum = max(maxsum, sum);
ans = min(ans, maxsum);
return ;
}
sum = 0;
for ( int i = index; i < n; i++) {
sum += a[i];
maxsum = max(maxsum, sum);
solve(a, n, k - 1, i + 1, sum, maxsum);
}
}
int main()
{
int arr[] = { 1, 2, 3, 4 };
int k = 3;
int n = 4;
solve(arr, n, k, 0, 0, 0);
cout << ans << "\n" ;
}
|
C
#include <stdio.h>
int ans = 100000000;
int max( int a, int b) { return a > b ? a : b; }
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)
{
if (k == 1) {
maxsum = max(maxsum, sum);
sum = 0;
for ( int i = index; i < n; i++) {
sum += a[i];
}
maxsum = max(maxsum, sum);
ans = min(ans, maxsum);
return ;
}
sum = 0;
for ( int i = index; i < n; i++) {
sum += a[i];
maxsum = max(maxsum, sum);
solve(a, n, k - 1, i + 1, sum, maxsum);
}
}
int main()
{
int arr[] = { 1, 2, 3, 4 };
int k = 3;
int n = 4;
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)
{
if (k == 1 ) {
maxsum = Math.max(maxsum, sum);
sum = 0 ;
for ( int i = index; i < n; i++) {
sum += a[i];
}
maxsum = Math.max(maxsum, sum);
ans = Math.min(ans, maxsum);
return ;
}
sum = 0 ;
for ( int i = index; i < n; i++) {
sum += a[i];
maxsum = Math.max(maxsum, sum);
solve(a, n, k - 1 , i + 1 , sum, maxsum);
}
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 4 };
int k = 3 ;
int n = 4 ;
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
if (k = = 1 ):
maxsum = max (maxsum, sum )
sum = 0
for i in range (index,n):
sum + = a[i]
maxsum = max (maxsum, sum )
ans = min (ans, maxsum)
return
sum = 0
for i in range (index, n):
sum + = a[i]
maxsum = max (maxsum, sum )
solve(a, n, k - 1 , i + 1 , sum , maxsum)
arr = [ 1 , 2 , 3 , 4 ]
k = 3
n = 4
solve(arr, n, k, 0 , 0 , 0 )
print (ans)
|
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)
{
if (k == 1) {
maxsum = Math.Max(maxsum, sum);
sum = 0;
for ( int i = index; i < n; i++) {
sum += a[i];
}
maxsum = Math.Max(maxsum, sum);
ans = Math.Min(ans, maxsum);
return ;
}
sum = 0;
for ( int i = index; i < n; i++) {
sum += a[i];
maxsum = Math.Max(maxsum, sum);
solve(a, n, k - 1, i + 1, sum, maxsum);
}
}
public static void Main(String[] args)
{
int []arr = { 1, 2, 3, 4 };
int k = 3;
int n = 4;
solve(arr, n, k, 0, 0, 0);
Console.Write(ans + "\n" );
}
}
|
Javascript
<script>
var ans = 10000000;
function solve(a, n, k, index, sum, maxsum)
{
if (k == 1) {
maxsum = Math.max(maxsum, sum);
sum = 0;
for ( var i = index; i < n; i++) {
sum += a[i];
}
maxsum = Math.max(maxsum, sum);
ans = Math.min(ans, maxsum);
return ;
}
sum = 0;
for ( var i = index; i < n; i++) {
sum += a[i];
maxsum = Math.max(maxsum, sum);
solve(a, n, k - 1, i + 1, sum, maxsum);
}
}
var arr = [ 1, 2, 3, 4 ];
var k = 3;
var n = 4;
solve(arr, n, k, 0, 0, 0);
document.write(ans + "\n" );
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
bool check( int mid, int array[], int n, int K)
{
int count = 0;
int sum = 0;
for ( int i = 0; i < n; i++) {
if (array[i] > mid)
return false ;
sum += array[i];
if (sum > mid) {
count++;
sum = array[i];
}
}
count++;
if (count <= K)
return true ;
return false ;
}
int solve( int array[], int n, int K)
{
int * max = max_element(array, array + n);
int start = *max;
int end = 0;
for ( int i = 0; i < n; i++) {
end += array[i];
}
int answer = 0;
while (start <= end) {
int mid = (start + end) / 2;
if (check(mid, array, n, K)) {
answer = mid;
end = mid - 1;
}
else {
start = mid + 1;
}
}
return answer;
}
int main()
{
int array[] = { 1, 2, 3, 4 };
int n = sizeof (array) / sizeof (array[0]);
int K = 3;
cout << solve(array, n, K);
}
|
Java
class GFG {
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 (array[i] > mid)
return false ;
sum += array[i];
if (sum > mid) {
count++;
sum = array[i];
}
}
count++;
if (count <= K)
return true ;
return false ;
}
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];
}
int end = 0 ;
for ( int i = 0 ; i < n; i++) {
end += array[i];
}
int answer = 0 ;
while (start <= end) {
int mid = (start + end) / 2 ;
if (check(mid, array, n, K)) {
answer = mid;
end = mid - 1 ;
}
else {
start = mid + 1 ;
}
}
return answer;
}
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));
}
}
|
Python3
def check(mid, array, n, K):
count = 0
sum = 0
for i in range (n):
if (array[i] > mid):
return False
sum + = array[i]
if ( sum > mid):
count + = 1
sum = array[i]
count + = 1
if (count < = K):
return True
return False
def solve(array, n, K):
start = max (array)
end = 0
for i in range (n):
end + = array[i]
answer = 0
while (start < = end):
mid = (start + end) / / 2
if (check(mid, array, n, K)):
answer = mid
end = mid - 1
else :
start = mid + 1
return answer
if __name__ = = '__main__' :
array = [ 1 , 2 , 3 , 4 ]
n = len (array)
K = 3
print (solve(array, n, K))
|
C#
using System;
class GFG
{
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 (array[i] > mid)
return false ;
sum += array[i];
if (sum > mid)
{
count++;
sum = array[i];
}
}
count++;
if (count <= K)
return true ;
return false ;
}
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];
}
int end = 0;
for ( int i = 0; i < n; i++)
{
end += array[i];
}
int answer = 0;
while (start <= end)
{
int mid = (start + end) / 2;
if (check(mid, array, n, K))
{
answer = mid;
end = mid - 1;
}
else
{
start = mid + 1;
}
}
return answer;
}
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));
}
}
|
Javascript
<script>
function check(mid, array, n, K)
{
var count = 0;
var sum = 0;
for ( var i = 0; i < n; i++) {
if (array[i] > mid)
return false ;
sum += array[i];
if (sum > mid) {
count++;
sum = array[i];
}
}
count++;
if (count <= K)
return true ;
return false ;
}
function solve(array, n, K)
{
var max = array.reduce((a,b)=>Math.max(a,b));
var start = max;
var end = 0;
for ( var i = 0; i < n; i++) {
end += array[i];
}
var answer = 0;
while (start <= end) {
var mid = parseInt((start + end) / 2);
if (check(mid, array, n, K)) {
answer = mid;
end = mid - 1;
}
else {
start = mid + 1;
}
}
return answer;
}
var array = [1, 2, 3, 4];
var n = array.length;
var K = 3;
document.write( solve(array, n, K));
</script>
|
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.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
08 May, 2023
Like Article
Save Article