Open In App

Find the maximum sum after dividing array A into M Subarrays

Last Updated : 18 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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




// C++ Implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function performing calculation
int MsubarraySum(vector<int>& A, int M)
{
 
    // Size of array A .
    int N = A.size();
 
    // Declaring difference array
    vector<int> diff(N - 1);
 
    // Storing difference between
    // adjacent elements of A
    for (int i = 0; i < N - 1; i++) {
 
        diff[i] = A[i + 1] - A[i];
    }
 
    // Sorting difference array
    // in increasing order.
    sort(diff.begin(), diff.end());
 
    // Initializing Answer variable
    int ans = A[N - 1] - A[0];
 
    // Running for loop and updating
    // answer variable
    for (int i = 0; i < M - 1; i++) {
        ans -= (diff[i]);
    }
 
    // Returning answer value
    return ans;
}
 
// Driver code
int main()
{
 
    vector<int> A = { 3, 6, 9, 10, 15 };
    int M = 3;
 
    // Function call
    cout << MsubarraySum(A, M);
    return 0;
}


Java




import java.util.*;
 
public class Main {
 
// Function performing calculation
public static int MsubarraySum(ArrayList<Integer> A, int M) {
 
    // Size of array A.
    int N = A.size();
 
    // Declaring difference array
    ArrayList<Integer> diff = new ArrayList<Integer>(N - 1);
 
    // Storing difference between
    // adjacent elements of A
    for (int i = 0; i < N - 1; i++) {
        diff.add(A.get(i + 1) - A.get(i));
    }
 
    // Sorting difference array
    // in increasing order.
    Collections.sort(diff);
 
    // Initializing Answer variable
    int ans = A.get(N - 1) - A.get(0);
 
    // Running for loop and updating
    // answer variable
    for (int i = 0; i < M - 1; i++) {
        ans -= (diff.get(i));
    }
 
    // Returning answer value
    return ans;
}
 
// Driver code
public static void main(String[] args) {
    ArrayList<Integer> A = new ArrayList<Integer>(Arrays.asList(3, 6, 9, 10, 15));
    int M = 3;
 
    // Function call
    System.out.println(MsubarraySum(A, M));
}
}


Python3




# Python Implementation of the above approach
 
# Function performing calculation
def MsubarraySum(A, M):
     
    # Size of array A.
    N = len(A)
 
    # Declaring difference array
    diff = [0] * (N - 1)
 
    # Storing difference between
    # adjacent elements of A
    for i in range(N - 1):
        diff[i] = A[i + 1] - A[i]
 
    # Sorting difference array
    # in increasing order.
    diff.sort()
 
    # Initializing Answer variable
    ans = A[N - 1] - A[0]
 
    # Running for loop and updating
    # answer variable
    for i in range(M - 1):
        ans -= diff[i]
 
    # Returning answer value
    return ans
 
# Driver code
A = [3, 6, 9, 10, 15]
M = 3
 
# Function call
print(MsubarraySum(A, M))
# This code is contributed by prasad264


Javascript




// Function performing calculation
function MsubarraySum(A, M) {
 
    // Size of array A
    let N = A.length;
 
    // Declaring difference array
    let diff = new Array(N - 1);
 
    // Storing difference between adjacent elements of A
    for (let i = 0; i < N - 1; i++) {
        diff[i] = A[i + 1] - A[i];
    }
 
    // Sorting difference array in increasing order
    diff.sort(function(a, b) {
        return a - b;
    });
 
    // Initializing Answer variable
    let ans = A[N - 1] - A[0];
 
    // Running for loop and updating answer variable
    for (let i = 0; i < M - 1; i++) {
        ans -= diff[i];
    }
 
    // Returning answer value
    return ans;
}
 
// Driver code
let A = [3, 6, 9, 10, 15];
let M = 3;
 
// Function call
console.log(MsubarraySum(A, M));


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class MainClass {
 
  // Function performing calculation
  public static int MsubarraySum(List<int> A, int M)
  {
 
    // Size of array A
    int N = A.Count;
 
    // Declaring difference array
    List<int> diff = new List<int>(N - 1);
 
    // Storing difference between
    // adjacent elements of A
    for (int i = 0; i < N - 1; i++) {
      diff.Add(A[i + 1] - A[i]);
    }
 
    // Sorting difference array
    // in increasing order.
    diff.Sort();
 
    // Initializing Answer variable
    int ans = A[N - 1] - A[0];
 
    // Running for loop and updating
    // answer variable
    for (int i = 0; i < M - 1; i++) {
      ans -= diff[i];
    }
 
    // Returning answer value
    return ans;
  }
 
  // Driver code
  public static void Main()
  {
    List<int> A = new List<int>{ 3, 6, 9, 10, 15 };
    int M = 3;
 
    // Function call
    Console.WriteLine(MsubarraySum(A, M));
  }
}


Output

8

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)
{
    // Size of array A.
    int N = A.size();
 
    // Declaring difference array
    vector<int> diff(N - 1, 0);
 
    // Storing difference between adjacent elements of A
    for (int i = 0; i < N - 1; i++) {
        diff[i] = A[i + 1] - A[i];
    }
 
    // Creating a min-heap from the difference array
    make_heap(diff.begin(), diff.end(), greater<int>());
 
    // Initializing Answer variable
    int ans = A[N - 1] - A[0];
 
    // Running for loop and updating answer variable
    for (int i = 0; i < M - 1; i++) {
        ans -= diff.front();
        pop_heap(diff.begin(), diff.end(), greater<int>());
        diff.pop_back();
    }
 
    // Returning answer value
    return ans;
}
 
// Driver code
int main()
{
    vector<int> A{ 3, 6, 9, 10, 15 };
    int M = 3;
 
    // Function call
    cout << MsubarraySum(A, M);
 
    return 0;
}
 
// This code is contributed by Susobhan Akhuli


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):
     
    # Size of array A.
    N = len(A)
 
    # Declaring difference array
    diff = [0] * (N - 1)
 
    # Storing difference between
    # adjacent elements of A
    for i in range(N - 1):
        diff[i] = A[i + 1] - A[i]
 
    # Creating a min-heap from the difference array
    heapq.heapify(diff)
 
    # Initializing Answer variable
    ans = A[N - 1] - A[0]
 
    # Running for loop and updating
    # answer variable
    for i in range(M - 1):
        ans -= heapq.heappop(diff)
 
    # Returning answer value
    return ans
 
# Driver code
A = [3, 6, 9, 10, 15]
M = 3
 
# Function call
print(MsubarraySum(A, M))


Javascript




function MsubarraySum(A, M) {
    // Size of array A.
    let N = A.length;
 
    // Declaring difference array
    let diff = new Array(N - 1).fill(0);
 
    // Storing difference between adjacent elements of A
    for (let i = 0; i < N - 1; i++) {
        diff[i] = A[i + 1] - A[i];
    }
 
    // Creating a min-heap from the difference array
    diff.sort((a, b) => a - b);
 
    // Initializing Answer variable
    let ans = A[N - 1] - A[0];
 
    // Running for loop and updating answer variable
    for (let i = 0; i < M - 1; i++) {
        ans -= diff[i];
    }
 
    // Returning answer value
    return ans;
}
 
// Driver code
let A = [3, 6, 9, 10, 15];
let M = 3;
 
// Function call
console.log(MsubarraySum(A, M)); // Output: 8


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG {
  static int MsubarraySum(List<int> A, int M)
  {
    // Size of list A.
    int N = A.Count;
 
    // Declaring difference array
    List<int> diff = new List<int>(N - 1);
 
    // Storing difference between adjacent elements of A
    for (int i = 0; i < N - 1; i++) {
      diff.Add(A[i + 1] - A[i]);
    }
 
    // Creating a min-heap from the difference array
    diff = new List<int>(
      new SortedSet<int>(diff).ToList());
 
    // Initializing Answer variable
    int ans = A[N - 1] - A[0];
 
    // Running for loop and updating answer variable
    for (int i = 0; i < M - 1; i++) {
      ans -= diff[0];
      diff.RemoveAt(0);
    }
 
    // Returning answer value
    return ans;
  }
 
  // Driver code
  static void Main(string[] args)
  {
    List<int> A = new List<int>{ 3, 6, 9, 10, 15 };
    int M = 3;
 
    // Function call
    Console.WriteLine(MsubarraySum(A, M));
  }
}
 
// This code is contributed by Susobhan Akhuli


Output

8

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.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads