Find the maximum sum after dividing array A into M Subarrays
Last Updated :
18 Apr, 2023
Given a sorted array A[] of size N and an integer M. You need to divide the array A[] into M non-empty consecutive subarray (1 ? M ? N) of any size such that each element is present in exactly one of the M-subarray. After dividing the array A[] into M subarrays you need to calculate the sum [max(i) – min(i)] where max(i) is the maximum element in the ith subarray and min(i) is the minimum element in the ith subarray (1 ? i ? M). After dividing array A into M subarrays, you need to compute the maximum sum.
Examples:
Input: A[] = {3, 6, 9, 10, 15}, M = 3
Output: 8
Explanation: The M subarrays are {3}, {6, 9}, {10, 15} and their maximum sum is 3-3 + 9-6 + 15-10 = 8
Input: A[] = {1, 2, 3, 4}, M = 4
Output: 0
Explanation: The M subarrays are {1}, {2}, {3}, {4} and their maximum sum is 1-1 + 2-2 + 3-3 + 4-4 = 0.
Approach: This can be solved with the following idea:
The idea is to check the co-efficient with which the array elements are included in the answer. If pair of adjacent elements Ai and Ai+1 belong to different subarrays then element Ai will be included in the answer with coefficient 1, and element Ai+1 with coefficient ?1. So they add value Ai?Ai+1 to the answer. If an element belongs to a subarray with length 1 then it will be included in the sum with coefficient 0 (because it will be included with coefficient 1 and ?1 simultaneously).
Elements at positions 1 and n will be included with coefficients ?1 and 1 respectively.
So initially our answer is An?A1. All we have to do is consider n?1 values A1?A2, A2?A3, …, An?1?An and add up the M?1 maximal ones to the answer
Below are the steps for the above approach:
- Declare a difference array diff of size N-1 which will store the difference between adjacent elements of array A[].
- Sort the difference array in increasing order.
- Initialize answer variable ans = A[N-1] – A[0] .
- Run a for loop from i = 0 to i < M-1 and update the answer variable ans = ans-diff[i].
- Return answer variable ans.
Below is the code for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int MsubarraySum(vector< int >& A, int M)
{
int N = A.size();
vector< int > diff(N - 1);
for ( int i = 0; i < N - 1; i++) {
diff[i] = A[i + 1] - A[i];
}
sort(diff.begin(), diff.end());
int ans = A[N - 1] - A[0];
for ( int i = 0; i < M - 1; i++) {
ans -= (diff[i]);
}
return ans;
}
int main()
{
vector< int > A = { 3, 6, 9, 10, 15 };
int M = 3;
cout << MsubarraySum(A, M);
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int MsubarraySum(ArrayList<Integer> A, int M) {
int N = A.size();
ArrayList<Integer> diff = new ArrayList<Integer>(N - 1 );
for ( int i = 0 ; i < N - 1 ; i++) {
diff.add(A.get(i + 1 ) - A.get(i));
}
Collections.sort(diff);
int ans = A.get(N - 1 ) - A.get( 0 );
for ( int i = 0 ; i < M - 1 ; i++) {
ans -= (diff.get(i));
}
return ans;
}
public static void main(String[] args) {
ArrayList<Integer> A = new ArrayList<Integer>(Arrays.asList( 3 , 6 , 9 , 10 , 15 ));
int M = 3 ;
System.out.println(MsubarraySum(A, M));
}
}
|
Python3
def MsubarraySum(A, M):
N = len (A)
diff = [ 0 ] * (N - 1 )
for i in range (N - 1 ):
diff[i] = A[i + 1 ] - A[i]
diff.sort()
ans = A[N - 1 ] - A[ 0 ]
for i in range (M - 1 ):
ans - = diff[i]
return ans
A = [ 3 , 6 , 9 , 10 , 15 ]
M = 3
print (MsubarraySum(A, M))
|
Javascript
function MsubarraySum(A, M) {
let N = A.length;
let diff = new Array(N - 1);
for (let i = 0; i < N - 1; i++) {
diff[i] = A[i + 1] - A[i];
}
diff.sort( function (a, b) {
return a - b;
});
let ans = A[N - 1] - A[0];
for (let i = 0; i < M - 1; i++) {
ans -= diff[i];
}
return ans;
}
let A = [3, 6, 9, 10, 15];
let M = 3;
console.log(MsubarraySum(A, M));
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class MainClass {
public static int MsubarraySum(List< int > A, int M)
{
int N = A.Count;
List< int > diff = new List< int >(N - 1);
for ( int i = 0; i < N - 1; i++) {
diff.Add(A[i + 1] - A[i]);
}
diff.Sort();
int ans = A[N - 1] - A[0];
for ( int i = 0; i < M - 1; i++) {
ans -= diff[i];
}
return ans;
}
public static void Main()
{
List< int > A = new List< int >{ 3, 6, 9, 10, 15 };
int M = 3;
Console.WriteLine(MsubarraySum(A, M));
}
}
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Approach 2: Using Min Heap
In this approach, we create a min-heap from the difference array, and then remove the smallest M-1 differences one by one, subtracting them from the answer variable. The remaining difference after subtracting M-1 differences from the answer is the required maximum subarray sum.
C++
#include <bits/stdc++.h>
using namespace std;
int MsubarraySum(vector< int > A, int M)
{
int N = A.size();
vector< int > diff(N - 1, 0);
for ( int i = 0; i < N - 1; i++) {
diff[i] = A[i + 1] - A[i];
}
make_heap(diff.begin(), diff.end(), greater< int >());
int ans = A[N - 1] - A[0];
for ( int i = 0; i < M - 1; i++) {
ans -= diff.front();
pop_heap(diff.begin(), diff.end(), greater< int >());
diff.pop_back();
}
return ans;
}
int main()
{
vector< int > A{ 3, 6, 9, 10, 15 };
int M = 3;
cout << MsubarraySum(A, M);
return 0;
}
|
Java
import java.util.*;
class Main {
public static int MsubarraySum(List<Integer> A, int M) {
int N = A.size();
List<Integer> diff = new ArrayList<Integer>(Collections.nCopies(N - 1 , 0 ));
for ( int i = 0 ; i < N - 1 ; i++) {
diff.set(i, A.get(i + 1 ) - A.get(i));
}
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
for ( int d : diff) {
minHeap.offer(d);
}
int ans = A.get(N - 1 ) - A.get( 0 );
for ( int i = 0 ; i < M - 1 ; i++) {
ans -= minHeap.poll();
}
return ans;
}
public static void main(String[] args) {
List<Integer> A = Arrays.asList( 3 , 6 , 9 , 10 , 15 );
int M = 3 ;
System.out.println(MsubarraySum(A, M));
}
}
|
Python3
import heapq
def MsubarraySum(A, M):
N = len (A)
diff = [ 0 ] * (N - 1 )
for i in range (N - 1 ):
diff[i] = A[i + 1 ] - A[i]
heapq.heapify(diff)
ans = A[N - 1 ] - A[ 0 ]
for i in range (M - 1 ):
ans - = heapq.heappop(diff)
return ans
A = [ 3 , 6 , 9 , 10 , 15 ]
M = 3
print (MsubarraySum(A, M))
|
Javascript
function MsubarraySum(A, M) {
let N = A.length;
let diff = new Array(N - 1).fill(0);
for (let i = 0; i < N - 1; i++) {
diff[i] = A[i + 1] - A[i];
}
diff.sort((a, b) => a - b);
let ans = A[N - 1] - A[0];
for (let i = 0; i < M - 1; i++) {
ans -= diff[i];
}
return ans;
}
let A = [3, 6, 9, 10, 15];
let M = 3;
console.log(MsubarraySum(A, M));
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static int MsubarraySum(List< int > A, int M)
{
int N = A.Count;
List< int > diff = new List< int >(N - 1);
for ( int i = 0; i < N - 1; i++) {
diff.Add(A[i + 1] - A[i]);
}
diff = new List< int >(
new SortedSet< int >(diff).ToList());
int ans = A[N - 1] - A[0];
for ( int i = 0; i < M - 1; i++) {
ans -= diff[0];
diff.RemoveAt(0);
}
return ans;
}
static void Main( string [] args)
{
List< int > A = new List< int >{ 3, 6, 9, 10, 15 };
int M = 3;
Console.WriteLine(MsubarraySum(A, M));
}
}
|
Time Complexity:
Creating a min-heap from the difference array takes O(N) time.
Removing the smallest M-1 differences from the heap takes O(M log N) time.
Updating the answer variable takes O(1) time.
Overall time complexity: O(N + M log N)
Auxiliary Space:
We use an extra space to store the difference array and create the min-heap, which takes O(N) space.
Share your thoughts in the comments
Please Login to comment...