Related Articles

# Split array into K subarrays such that sum of maximum of all subarrays is maximized

• Difficulty Level : Expert
• Last Updated : 17 Jun, 2021

Given an array arr[] of size N and a number K, the task is to partition the given array into K contiguous subarrays such that the sum of the maximum of each subarray is the maximum possible. If it is possible to split the array in such a manner, then print the maximum possible sum. Otherwise, print “-1“.

Examples:

Input: arr[] = {5, 3, 2, 7, 6, 4}, N = 6, K = 3
Output: 18
5
3 2 7
6 4
Explanation:
One way is to split the array at indices 0, 3 and 4.
Therefore, the subarrays formed are {5}, {3, 2, 7} and {6, 4}.
Therefore, sum of the maximum of each subarray = 5 + 7 + 6 =18 ( which is the maximum possible).

Input: arr[] = {1, 4, 5, 6, 1, 2}, N = 6, K = 2
Output: 11

Approach: The given problem can be solved using Map data structure and Sorting techniques, based on the following observations:

• The maximum obtainable sum would be the sum of the K-largest elements of the array as it is always possible to divide the array into K segments in such a way that the maximum of each segment is one of the K-largest elements.
• One way would be to break a segment as soon as one of the K-largest element is encountered.

Follow the steps below to solve the problem:

• First, if N is less than K then print “-1” and then return.
• Copy array into another array say temp[] and sort the array, temp[] in descending order.
• Initialize a variable ans to 0, to store the maximum sum possible.
• Also, Initialize a map say mp, to store the frequency of the K-largest elements.
• Iterate in the range [0, K-1] using a variable say i, and in each iteration increment the ans by temp[i] and increment the count of temp[i] in map mp.
• Initialize a vector of vectors say P to store a possible partition and a vector say V to store the elements of a partition.
• Iterate in the range [0, N-1] and using a variable say i and perform the following steps:
• Push the current element arr[i] in the vector V.
• If mp[arr[i]] is greater than 0 then do the following:
• Decrement K and count of arr[i] in the map mp by 1.
• If K is equal to 0 i.e it is the last segment then push all the remaining elements of the array arr[] in V.
• Now push the current segment V in the P.
• Finally, after completing the above steps, print the maximum sum stores in variable ans and then partition stored in P.

Below is the implementation of the above approach:

## C++

 `// C++ program for tha above approach``#include ``using` `namespace` `std;` `// Function to split the array into K``// subarrays such that the sum of``// maximum of each subarray is maximized``void` `partitionIntoKSegments(``int` `arr[],``                            ``int` `N, ``int` `K)``{``    ``// If N is less than K``    ``if` `(N < K) {``        ``cout << -1 << endl;``        ``return``;``    ``}``    ``// Map to store the K``    ``// largest elements``    ``map<``int``, ``int``> mp;` `    ``// Auxiliary array to``    ``// store and sort arr[]``    ``int` `temp[N];` `    ``// Stores the maximum sum``    ``int` `ans = 0;` `    ``// Copy arr[] to temp[]``    ``for` `(``int` `i = 0; i < N; i++) {``        ``temp[i] = arr[i];``    ``}` `    ``// Sort array temp[] in``    ``// descending order``    ``sort(temp, temp + N,``         ``greater<``int``>());` `    ``// Iterate in the range [0, K - 1]``    ``for` `(``int` `i = 0; i < K; i++) {` `        ``// Increment sum by temp[i]``        ``ans += temp[i];` `        ``// Increment count of``        ``// temp[i] in the map mp``        ``mp[temp[i]]++;``    ``}` `    ``// Stores the partitions``    ``vector > P;` `    ``// Stores temporary subarrays``    ``vector<``int``> V;` `    ``// Iterate over the range [0, N - 1]``    ``for` `(``int` `i = 0; i < N; i++) {``        ``V.push_back(arr[i]);` `        ``// If current element is``        ``// one of the K largest``        ``if` `(mp[arr[i]] > 0) {` `            ``mp[arr[i]]--;``            ``K--;` `            ``if` `(K == 0) {``                ``i++;``                ``while` `(i < N) {``                    ``V.push_back(arr[i]);``                    ``i++;``                ``}``            ``}` `            ``if` `(V.size()) {``                ``P.push_back(V);``                ``V.clear();``            ``}``        ``}``    ``}` `    ``// Print the ans``    ``cout << ans << endl;` `    ``// Print the partition``    ``for` `(``auto` `u : P) {``        ``for` `(``auto` `x : u)``            ``cout << x << ``" "``;``        ``cout << endl;``    ``}``}``// Driver code``int` `main()``{``    ``// Input``    ``int` `A[] = { 5, 3, 2, 7, 6, 4 };``    ``int` `N = ``sizeof``(A) / ``sizeof``(A);``    ``int` `K = 3;` `    ``// Function call``    ``partitionIntoKSegments(A, N, K);``    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;``public` `class` `GFG``{` `// Function to split the array into K``// subarrays such that the sum of``// maximum of each subarray is maximized``static` `void` `partitionIntoKSegments(``int` `arr[], ``int` `N, ``int` `K)``{``    ` `    ``// If N is less than K``    ``if` `(N < K)``    ``{``         ``System.out.println(-``1``);``        ``return``;``    ``}``    ` `    ``// Map to store the K``    ``// largest elements``    ``HashMap mp = ``new` `HashMap();` `    ``// Auxiliary array to``    ``// store and sort arr[]``    ``Integer []temp = ``new` `Integer[N];` `    ``// Stores the maximum sum``    ``int` `ans = ``0``;` `    ``// Copy arr[] to temp[]``    ``for``(``int` `i = ``0``; i < N; i++)``    ``{``        ``temp[i] = arr[i];``    ``}` `    ``// Sort array temp[] in``    ``// descending order``    ``Arrays.sort(temp,Collections.reverseOrder());``    ``//Array.Reverse(temp);` `    ``// Iterate in the range [0, K - 1]``    ``for``(``int` `i = ``0``; i < K; i++)``    ``{``        ` `        ``// Increment sum by temp[i]``        ``ans += temp[i];` `        ``// Increment count of``        ``// temp[i] in the map mp``        ``if` `(mp.containsKey(temp[i]))``            ``mp.get(temp[i]++);``        ``else``            ``mp.put(temp[i], ``1``);``    ``}` `    ``// Stores the partitions``    ``ArrayList> P = ``new` `ArrayList>();` `    ``// Stores temporary subarrays``    ``ArrayList V = ``new` `ArrayList();` `    ``// Iterate over the range [0, N - 1]``    ``for``(``int` `i = ``0``; i < N; i++)``    ``{``        ``V.add(arr[i]);``    ` `        ``// If current element is``        ``// one of the K largest``        ``if` `(mp.containsKey(arr[i]) && mp.get(arr[i]) > ``0``)``        ``{``            ``mp.get(arr[i]--);``            ``K--;` `            ``if` `(K == ``0``)``            ``{``                ``i++;``                ` `                ``while` `(i < N)``                ``{``                    ``V.add(arr[i]);``                    ``i++;``                ``}``            ``}` `            ``if` `(V.size() > ``0``)``            ``{``                ``P.add(``new` `ArrayList(V));``                ``V.clear();``            ``}``        ``}``    ``}` `    ``// Print the ans``     ``System.out.println(ans);``    ` `    ``// Print the partition``    ``for` `(ArrayList subList : P)``    ``{``        ``for``(Integer  item : subList)``        ``{``              ``System.out.print(item+``" "``);``        ``}``         ``System.out.println();``    ``}``}` `// Driver code``public` `static` `void` `main(String args[])``{``    ` `    ``// Input``    ``int` `[]A = { ``5``, ``3``, ``2``, ``7``, ``6``, ``4` `};``    ``int` `N = A.length;``    ``int` `K = ``3``;` `    ``// Function call``    ``partitionIntoKSegments(A, N, K);``}``}` `// This code is contributed by SoumikMondal`

## Python3

 `# Python program for tha above approach` `# Function to split the array into K``# subarrays such that the sum of``# maximum of each subarray is maximized``def` `partitionIntoKSegments(arr, N, K):``    ``# If N is less than K``    ``if` `(N < K):``        ``print``(``-``1``)``        ``return``    ``# Map to store the K``    ``# largest elements``    ``mp ``=` `{}` `    ``# Auxiliary array to``    ``# store and sort arr[]``    ``temp ``=` `[``0``]``*``N` `    ``# Stores the maximum sum``    ``ans ``=` `0` `    ``# Copy arr[] to temp[]``    ``for` `i ``in` `range``(N):``        ``temp[i] ``=` `arr[i]` `    ``# Sort array temp[] in``    ``# descending order``    ``temp ``=` `sorted``(temp)[::``-``1``]` `    ``# Iterate in the range [0, K - 1]``    ``for` `i ``in` `range``(K):``        ``# Increment sum by temp[i]``        ``ans ``+``=` `temp[i]` `        ``# Increment count of``        ``# temp[i] in the map mp``        ``mp[temp[i]] ``=` `mp.get(temp[i], ``0``) ``+` `1` `    ``# Stores the partitions``    ``P ``=` `[]` `    ``# Stores temporary subarrays``    ``V ``=` `[]` `    ``# Iterate over the range [0, N - 1]``    ``for` `i ``in` `range``(N):``        ``V.append(arr[i])` `        ``# If current element is``        ``# one of the K largest``        ``if` `(arr[i] ``in` `mp):` `            ``mp[arr[i]] ``-``=` `1``            ``K ``-``=` `1` `            ``if` `(K ``=``=` `0``):``                ``i ``+``=` `1``                ``while` `(i < N):``                    ``V.append(arr[i])``                    ``i ``+``=` `1``            ``# print(V)` `            ``if` `(``len``(V) > ``0``):``                ``P.append(``list``(V))``                ``V.clear()` `    ``# Prthe ans``    ``print``(ans)` `    ``# Prthe partition``    ``for` `u ``in` `P:``        ``for` `x ``in` `u:``            ``print``(x,end``=``" "``)``        ``print``()``# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ``# Input``    ``A ``=` `[``5``, ``3``, ``2``, ``7``, ``6``, ``4``]``    ``N ``=` `len``(A)``    ``K ``=` `3` `    ``# Function call``    ``partitionIntoKSegments(A, N, K)` `# This code is contributed by mohit kumar 29.`

## C#

 `// C# program for tha above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{` `// Function to split the array into K``// subarrays such that the sum of``// maximum of each subarray is maximized``static` `void` `partitionIntoKSegments(``int` `[]arr,``                                   ``int` `N, ``int` `K)``{``    ` `    ``// If N is less than K``    ``if` `(N < K)``    ``{``        ``Console.WriteLine(-1);``        ``return``;``    ``}``    ` `    ``// Map to store the K``    ``// largest elements``    ``Dictionary<``int``,``               ``int``> mp = ``new` `Dictionary<``int``,``                                        ``int``>();` `    ``// Auxiliary array to``    ``// store and sort arr[]``    ``int` `[]temp = ``new` `int``[N];` `    ``// Stores the maximum sum``    ``int` `ans = 0;` `    ``// Copy arr[] to temp[]``    ``for``(``int` `i = 0; i < N; i++)``    ``{``        ``temp[i] = arr[i];``    ``}` `    ``// Sort array temp[] in``    ``// descending order``    ``Array.Sort(temp);``    ``Array.Reverse(temp);` `    ``// Iterate in the range [0, K - 1]``    ``for``(``int` `i = 0; i < K; i++)``    ``{``        ` `        ``// Increment sum by temp[i]``        ``ans += temp[i];` `        ``// Increment count of``        ``// temp[i] in the map mp``        ``if` `(mp.ContainsKey(temp[i]))``            ``mp[temp[i]]++;``        ``else``            ``mp.Add(temp[i],1);``    ``}` `    ``// Stores the partitions``    ``List> P = ``new` `List>();` `    ``// Stores temporary subarrays``    ``List<``int``> V = ``new` `List<``int``>();` `    ``// Iterate over the range [0, N - 1]``    ``for``(``int` `i = 0; i < N; i++)``    ``{``        ``V.Add(arr[i]);``    ` `        ``// If current element is``        ``// one of the K largest``        ``if` `(mp.ContainsKey(arr[i]) && mp[arr[i]] > 0)``        ``{``            ``mp[arr[i]]--;``            ``K--;` `            ``if` `(K == 0)``            ``{``                ``i++;``                ` `                ``while` `(i < N)``                ``{``                    ``V.Add(arr[i]);``                    ``i++;``                ``}``            ``}` `            ``if` `(V.Count > 0)``            ``{``                ``P.Add(``new` `List<``int``>(V));``                ``V.Clear();``            ``}``        ``}``    ``}` `    ``// Print the ans``    ``Console.WriteLine(ans);``    ` `    ``// Print the partition``    ``foreach` `(List<``int``> subList ``in` `P)``    ``{``        ``foreach` `(``int` `item ``in` `subList)``        ``{``            ``Console.Write(item+``" "``);``        ``}``        ``Console.WriteLine();``    ``}``}` `// Driver code``public` `static` `void` `Main()``{``    ` `    ``// Input``    ``int` `[]A = { 5, 3, 2, 7, 6, 4 };``    ``int` `N = A.Length;``    ``int` `K = 3;` `    ``// Function call``    ``partitionIntoKSegments(A, N, K);``}``}` `// This code is contributed by SURENDRA_GANGWAR`

## Javascript

 ``
Output:
```18
5
3 2 7
6 4```

Time Complexity: O(N*log(N))
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up