# Divide a sorted array in K parts with sum of difference of max and min minimized in each part – Set 2

Last Updated : 18 Jan, 2022

Given an ascending sorted array arr[] of size N and an integer K, the task is to partition the given array into K non-empty subarrays such that the sum of differences of the maximum and the minimum of each subarray is minimized.

Examples:

Input: arr[] = { 10, 20, 70, 80 },  N = 4, K = 2
Output: 20
Explanation: The given array can be split in the following way
{10, 20} and {70, 80}. The differences are (20 – 10) = 10 and (80 – 70) = 10
The sum = 10 + 10 = 20

Input:  arr[] = { 5, 10, 50, 70 }, N = 4, K = 3
Output: 5
Explanation: The subarrays are {5, 10}, {50}, {70}
The differences are 10 – 5 = 5, 50 – 50 = 0, 70 – 70 = 0
The sum = 5 + 0 + 0 = 5

Approach: The other approaches are discussed in Set 1 of this article. Here, we are discussing the Binary Search approach.

Space Optimized Approach: The idea is to use binary search in order to find the answer. The answer lies in [ 0, ( arr[N-1] – arr[0]) ]. See the following observation for justification.

• Assuming permission to make as many cuts as possible, the answer would be 0 because each element can form a subarray. Thus the minimum value would be 0.
• Now the other extreme case can be when only one subarray is allowed, In this case, the answer would be (arr[N-1] – arr[0]). These were the two extreme cases and it is guaranteed that the answer would lie in between them.

Follow the steps below to solve the problem:

• Initialize the variable ans as 0 to store the answer.
• Apply binary search with low = 0, and high = arr[N-1] – arr[0].
• For each value of mid, check if a tape of length mid can cover all the holes within K cuts.
• If so then we have arrived at a potential answer. Store the value and check if it is possible to do the same for a smaller length of tape. (make high = mid – 1 )
• If not then find a larger value for mid (low = mid + 1).

Below is the implementation of the above approach.

## C++

 // C++ program for the above approach #include using namespace std;   bool isValid(vector arr, int max_cuts, int len) {       // Max_cuts is the maximum no. of     // allowed cuts.     int n = arr.size();     int start = 0;     int i = 1;     while (i < n) {           // Start from covering as many holes         // as you can from start.         if (arr[i] - arr[start] <= len) {             i++;         }         else {               // If an index is reached             // from where it's not possible             // to accommodate more elements             // in the current subarray             // then end this subarray             // and go further.             len = len - (arr[i - 1] - arr[start]);             max_cuts--;             start = i;             i++;         }           // If at any point you run out         // of maximum subarrays or length         // then return false because it's         // impossible to obtain this         // value of mid.         if (max_cuts <= 0 || len <= 0)             return false;     }       // Covered all subarrays within     // the sum maximum number of subarrays     // so return true.     return true; }   // Function to find the minimum sum void findMinTapeLength(vector arr, int N, int K) {     // Initialise low and high     int high = arr[N - 1] - arr[0], low = 0;     int ans = 0;       // Apply Binary Search     while (low <= high) {         int mid = low + (high - low) / 2;           // IsValid() function checks if         // max value of mid is sufficient         // to break the array in K subarrays         if (isValid(arr, K, mid)) {               // If true then set this as             // the current answer and divide             // your range to [low, mid-1]             // to check for a lower sum             ans = mid;             high = mid - 1;         }         // If false then that means need         // to increase the current length         // so set range to [mid+1, high]         else             low = mid + 1;     }     cout << ans; }   // Driver Code int main() {     vector arr = { 10, 20, 70, 80 };     int N = 4, K = 2;     findMinTapeLength(arr, N, K); }   // This code is contributed by Samim Hossain Mondal.

## Java

 // Java program for the above approach import java.io.*;   class GFG {       // Function to find the minimum sum     static void findMinTapeLength(int[] arr,                                   int N, int K)     {         // Initialise low and high         int high = arr[N - 1] - arr[0], low = 0;         int ans = 0;           // Apply Binary Search         while (low <= high) {             int mid = low + (high - low) / 2;               // IsValid() function checks if             // max value of mid is sufficient             // to break the array in K subarrays             if (isValid(arr, K, mid)) {                   // If true then set this as                 // the current answer and divide                 // your range to [low, mid-1]                 // to check for a lower sum                 ans = mid;                 high = mid - 1;             }             // If false then that means need             // to increase the current length             // so set range to [mid+1, high]             else                 low = mid + 1;         }         System.out.println(ans);     }       static boolean isValid(int[] arr,                            int max_cuts,                            int len)     {           // Max_cuts is the maximum no. of         // allowed cuts.         int n = arr.length;         int start = 0;         int i = 1;         while (i < n) {               // Start from covering as many holes             // as you can from start.             if (arr[i] - arr[start] <=                 len) {                 i++;             }             else {                   // If an index is reached                 // from where it's not possible                 // to accommodate more elements                 // in the current subarray                 // then end this subarray                 // and go further.                 len = len - (arr[i - 1] -                              arr[start]);                 max_cuts--;                 start = i;                 i++;             }               // If at any point you run out             // of maximum subarrays or length             // then return false because it's             // impossible to obtain this             // value of mid.             if (max_cuts <= 0 || len <= 0)                 return false;         }           // Covered all subarrays within         // the sum maximum number of subarrays         // so return true.         return true;     }       // Driver Code     public static void main(String[] args)     {         int[] arr = { 10, 20, 70, 80 };         int N = 4, K = 2;         findMinTapeLength(arr, N, K);     } }

## Python3

 # Python code for the above approach   # Function to find the minimum sum def findMinTapeLength(arr, N, K):       # Initialise low and high     high = arr[N - 1] - arr[0]     low = 0     ans = 0       # Apply Binary Search     while (low <= high):         mid = low + ((high - low) // 2)           # IsValid() function checks if         # max value of mid is sufficient         # to break the array in K subarrays         if (isValid(arr, K, mid)):               # If true then set this as             # the current answer and divide             # your range to [low, mid-1]             # to check for a lower sum             ans = mid             high = mid - 1           # If false then that means need         # to increase the current length         # so set range to [mid+1, high]         else:             low = mid + 1     print(ans)     def isValid(arr, max_cuts, _len):       # Max_cuts is the maximum no. of     # allowed cuts.     n = len(arr)     start = 0     i = 1     while (i < n):           # Start from covering as many holes         # as you can from start.         if (arr[i] - arr[start] <= _len):             i += 1         else:               # If an index is reached             # from where it's not possible             # to accommodate more elements             # in the current subarray             # then end this subarray             # and go further.             _len = _len - (arr[i - 1] - arr[start])             max_cuts -= 1             start = i             i += 1           # If at any point you run out         # of maximum subarrays or length         # then return false because it's         # impossible to obtain this         # value of mid.         if (max_cuts <= 0 or _len <= 0):             return False       # Covered all subarrays within     # the sum maximum number of subarrays     # so return true.     return True     # Driver Code arr = [10, 20, 70, 80] N = 4 K = 2 findMinTapeLength(arr, N, K)   # This code is contributed by gfgking

## C#

 // C# program for the above approach using System; class GFG {     // Function to find the minimum sum   static void findMinTapeLength(int[] arr,                                 int N, int K)   {       // Initialise low and high     int high = arr[N - 1] - arr[0], low = 0;     int ans = 0;       // Apply Binary Search     while (low <= high) {       int mid = low + (high - low) / 2;         // IsValid() function checks if       // max value of mid is sufficient       // to break the array in K subarrays       if (isValid(arr, K, mid)) {           // If true then set this as         // the current answer and divide         // your range to [low, mid-1]         // to check for a lower sum         ans = mid;         high = mid - 1;       }         // If false then that means need       // to increase the current length       // so set range to [mid+1, high]       else         low = mid + 1;     }     Console.WriteLine(ans);   }     static bool isValid(int[] arr,                       int max_cuts,                       int len)   {       // Max_cuts is the maximum no. of     // allowed cuts.     int n = arr.Length;     int start = 0;     int i = 1;     while (i < n) {         // Start from covering as many holes       // as you can from start.       if (arr[i] - arr[start] <=           len) {         i++;       }       else {           // If an index is reached         // from where it's not possible         // to accommodate more elements         // in the current subarray         // then end this subarray         // and go further.         len = len - (arr[i - 1] -                      arr[start]);         max_cuts--;         start = i;         i++;       }         // If at any point you run out       // of maximum subarrays or length       // then return false because it's       // impossible to obtain this       // value of mid.       if (max_cuts <= 0 || len <= 0)         return false;     }       // Covered all subarrays within     // the sum maximum number of subarrays     // so return true.     return true;   }     // Driver Code   public static void Main()   {     int[] arr = { 10, 20, 70, 80 };     int N = 4, K = 2;     findMinTapeLength(arr, N, K);   } }   // This code is contributed by Samim Hossain Mondal.

## Javascript



Output

20

Time Complexity: O(N*log(M)), where M is the maximum value of the array.
Auxiliary Space: O(1)