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 <bits/stdc++.h>
using namespace std;
bool isValid(vector<int> 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<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;
}
cout << ans;
}
// Driver Code
int main()
{
vector<int> 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
<script>
// JavaScript code for the above approach
// Function to find the minimum sum
function findMinTapeLength(arr,
N, K)
{
// Initialise low and high
let high = arr[N - 1] - arr[0], low = 0;
let ans = 0;
// Apply Binary Search
while (low <= high)
{
let mid = low + Math.floor((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;
}
document.write(ans);
}
function isValid(arr, max_cuts, len)
{
// Max_cuts is the maximum no. of
// allowed cuts.
let n = arr.length;
let start = 0;
let 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
let arr = [10, 20, 70, 80];
let N = 4, K = 2;
findMinTapeLength(arr, N, K);
// This code is contributed by Potta Lokesh
</script>
Time Complexity: O(N*log(M)), where M is the maximum value of the array.
Auxiliary Space: O(1)
Similar Reads
Divide a sorted array in K parts with sum of difference of max and min minimized in each part 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[] = {4, 8, 15, 16, 23, 42}, K = 3 Output: 12 Expla
7 min read
Split array into K Subarrays to minimize sum of difference between min and max Given a sorted array arr[] of size N and integer K, the task is to split the array into K non-empty subarrays such that the sum of the difference between the maximum element and the minimum element of each subarray is minimized. Note: Every element of the array must be included in one subarray and e
6 min read
Find the sum of maximum difference possible from all subset of a given array. We are given an array arr[] of n non-negative integers (repeated elements allowed), find out the sum of maximum difference possible from all subsets of the given array. Suppose max(s) represents the maximum value in any subset 's' whereas min(s) represents the minimum value in the set 's'. We need t
7 min read
Minimum difference between maximum and minimum value of Array with given Operations Given an array arr[] and an integer K. The following operations can be performed on any array element: Multiply the array element with K.If the element is divisible by K, then divide it by K. The above two operations can be applied any number of times including zero on any array element. The task is
9 min read
Split a given array into K subarrays minimizing the difference between their maximum and minimum Given a sorted array arr[] of N integers and an integer K, the task is to split the array into K subarrays such that the sum of the difference of maximum and minimum element of each subarray is minimized. Examples: Input: arr[] = {1, 3, 3, 7}, K = 4 Output: 0 Explanation: The given array can be spli
6 min read