Divide a sorted array in K parts with sum of difference of max and min minimized in each part – Set 2
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++
#include <bits/stdc++.h>
using namespace std;
bool isValid(vector< int > arr, int max_cuts, int len)
{
int n = arr.size();
int start = 0;
int i = 1;
while (i < n) {
if (arr[i] - arr[start] <= len) {
i++;
}
else {
len = len - (arr[i - 1] - arr[start]);
max_cuts--;
start = i;
i++;
}
if (max_cuts <= 0 || len <= 0)
return false ;
}
return true ;
}
void findMinTapeLength(vector< int > arr, int N, int K)
{
int high = arr[N - 1] - arr[0], low = 0;
int ans = 0;
while (low <= high) {
int mid = low + (high - low) / 2;
if (isValid(arr, K, mid)) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
cout << ans;
}
int main()
{
vector< int > arr = { 10, 20, 70, 80 };
int N = 4, K = 2;
findMinTapeLength(arr, N, K);
}
|
Java
import java.io.*;
class GFG {
static void findMinTapeLength( int [] arr,
int N, int K)
{
int high = arr[N - 1 ] - arr[ 0 ], low = 0 ;
int ans = 0 ;
while (low <= high) {
int mid = low + (high - low) / 2 ;
if (isValid(arr, K, mid)) {
ans = mid;
high = mid - 1 ;
}
else
low = mid + 1 ;
}
System.out.println(ans);
}
static boolean isValid( int [] arr,
int max_cuts,
int len)
{
int n = arr.length;
int start = 0 ;
int i = 1 ;
while (i < n) {
if (arr[i] - arr[start] <=
len) {
i++;
}
else {
len = len - (arr[i - 1 ] -
arr[start]);
max_cuts--;
start = i;
i++;
}
if (max_cuts <= 0 || len <= 0 )
return false ;
}
return true ;
}
public static void main(String[] args)
{
int [] arr = { 10 , 20 , 70 , 80 };
int N = 4 , K = 2 ;
findMinTapeLength(arr, N, K);
}
}
|
Python3
def findMinTapeLength(arr, N, K):
high = arr[N - 1 ] - arr[ 0 ]
low = 0
ans = 0
while (low < = high):
mid = low + ((high - low) / / 2 )
if (isValid(arr, K, mid)):
ans = mid
high = mid - 1
else :
low = mid + 1
print (ans)
def isValid(arr, max_cuts, _len):
n = len (arr)
start = 0
i = 1
while (i < n):
if (arr[i] - arr[start] < = _len):
i + = 1
else :
_len = _len - (arr[i - 1 ] - arr[start])
max_cuts - = 1
start = i
i + = 1
if (max_cuts < = 0 or _len < = 0 ):
return False
return True
arr = [ 10 , 20 , 70 , 80 ]
N = 4
K = 2
findMinTapeLength(arr, N, K)
|
C#
using System;
class GFG {
static void findMinTapeLength( int [] arr,
int N, int K)
{
int high = arr[N - 1] - arr[0], low = 0;
int ans = 0;
while (low <= high) {
int mid = low + (high - low) / 2;
if (isValid(arr, K, mid)) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
Console.WriteLine(ans);
}
static bool isValid( int [] arr,
int max_cuts,
int len)
{
int n = arr.Length;
int start = 0;
int i = 1;
while (i < n) {
if (arr[i] - arr[start] <=
len) {
i++;
}
else {
len = len - (arr[i - 1] -
arr[start]);
max_cuts--;
start = i;
i++;
}
if (max_cuts <= 0 || len <= 0)
return false ;
}
return true ;
}
public static void Main()
{
int [] arr = { 10, 20, 70, 80 };
int N = 4, K = 2;
findMinTapeLength(arr, N, K);
}
}
|
Javascript
<script>
function findMinTapeLength(arr,
N, K)
{
let high = arr[N - 1] - arr[0], low = 0;
let ans = 0;
while (low <= high)
{
let mid = low + Math.floor((high - low) / 2);
if (isValid(arr, K, mid)) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
document.write(ans);
}
function isValid(arr, max_cuts, len)
{
let n = arr.length;
let start = 0;
let i = 1;
while (i < n) {
if (arr[i] - arr[start] <=
len) {
i++;
}
else {
len = len - (arr[i - 1] -
arr[start]);
max_cuts--;
start = i;
i++;
}
if (max_cuts <= 0 || len <= 0)
return false ;
}
return true ;
}
let arr = [10, 20, 70, 80];
let N = 4, K = 2;
findMinTapeLength(arr, N, K);
</script>
|
Time Complexity: O(N*log(M)), where M is the maximum value of the array.
Auxiliary Space: O(1)
Last Updated :
18 Jan, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...