Split an Array to maximize subarrays having equal count of odd and even elements for a cost not exceeding K
Last Updated :
23 Apr, 2021
Given an array arr[] of size N and an integer K, the task is to split the given array into maximum possible subarrays having equal count of even and odd elements such that the cost to split the array does not exceed K.
The cost to split an array into a subarray is the difference between the last and first elements of the subarrays respectively.
Examples:
Input: arr[] = {1, 2, 5, 10, 15, 20}, K = 4
Output: 1
Explanation:
The optimal way is to split the array between 2 and 5.
So it splits into {1, 2} and {5, 10, 15, 20}.
Also, both the subarrays contain an equal number of even and odd elements. The cost of the split is abs(2 – 5) = 3 which is ? K.
Input: arr[] = {1, 2, 3, 4, 5, 6}, K = 100
Output: 2
Explanation:
The optimal way is to make two splits such that the subarrays formed are {1, 2}, {3, 4}, {5, 6}.
The total cost is abs(2 – 3) + abs(4 – 5) = 2
Naive Approach: The simplest approach to solve this problem is as follows:
- Split the array at every index and check if the cost is less than K or not.
- If the cost is less than K, then check if the number of odd and even elements in the subarray are equal or not.
- Now check if another split is possible or not by repeating the same steps.
- After checking all possible splits, print the minimum cost which add up to a sum less than K.
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: The idea is to maintain the counters which store the number of even numbers and odd numbers in the array. Below are the steps:
- Initialize an array (say poss[]) which stores the cost of all possible splits.
- Traverse through the array arr[]. For every index, check if the subarray up to this index and the subarray starting from the next index has equal count of odd and even elements.
- If the above condition satisfies, then a split is possible. Store the cost associated with this split in poss[].
- Repeat the above steps for all the elements in the array and store the costs of every split.
- Cost of split at index i can be obtained by abs(arr[i + 1] – arr[i]).
- Now, in order to find the maximum number of possible splits, sort the array poss[] that contains the costs of each possible split.
- Now select all minimum costs from poss[] whose sum is less than or equal to K.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int make_cuts( int arr[], int n, int K)
{
int ans = 0;
vector< int > poss;
int ce = 0;
int co = 0;
for ( int x = 0; x < n - 1; x++) {
if (arr[x] % 2 == 0)
ce++;
else
co++;
if (ce == co && co > 0
&& ce > 0) {
poss.push_back(
abs (arr[x]
- arr[x + 1]));
}
}
sort(poss.begin(), poss.end());
for ( int x : poss) {
if (K >= x) {
ans++;
K -= x;
}
else
break ;
}
return ans;
}
int main()
{
int N = 6;
int K = 4;
int arr[] = { 1, 2, 5, 10, 15, 20 };
cout << make_cuts(arr, N, K);
}
|
Java
import java.util.*;
class GFG{
static int make_cuts( int arr[], int n, int K)
{
int ans = 0 ;
Vector<Integer> poss = new Vector<Integer>();
int ce = 0 ;
int co = 0 ;
for ( int x = 0 ; x < n - 1 ; x++)
{
if (arr[x] % 2 == 0 )
ce++;
else
co++;
if (ce == co && co > 0 && ce > 0 )
{
poss.add(Math.abs(arr[x] -
arr[x + 1 ]));
}
}
Collections.sort(poss);
for ( int x : poss)
{
if (K >= x)
{
ans++;
K -= x;
}
else
break ;
}
return ans;
}
public static void main(String[] args)
{
int N = 6 ;
int K = 4 ;
int arr[] = { 1 , 2 , 5 , 10 , 15 , 20 };
System.out.print(make_cuts(arr, N, K));
}
}
|
Python3
def make_cuts(arr, n, K):
ans = 0
poss = []
ce = 0
co = 0
for x in range (n - 1 ):
if (arr[x] % 2 = = 0 ):
ce + = 1
else :
co + = 1
if (ce = = co and co > 0 and ce > 0 ):
poss.append( abs (arr[x] -
arr[x + 1 ]))
poss.sort()
for x in poss:
if (K > = x):
ans + = 1
K - = x
else :
break
return ans
N = 6
K = 4
arr = [ 1 , 2 , 5 , 10 , 15 , 20 ]
print (make_cuts(arr, N, K))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int make_cuts( int []arr, int n, int K)
{
int ans = 0;
List< int > poss = new List< int >();
int ce = 0;
int co = 0;
for ( int x = 0; x < n - 1; x++)
{
if (arr[x] % 2 == 0)
ce++;
else
co++;
if (ce == co && co > 0 && ce > 0)
{
poss.Add(Math.Abs(arr[x] -
arr[x + 1]));
}
}
poss.Sort();
foreach ( int x in poss)
{
if (K >= x)
{
ans++;
K -= x;
}
else
break ;
}
return ans;
}
public static void Main(String[] args)
{
int N = 6;
int K = 4;
int []arr = { 1, 2, 5, 10, 15, 20 };
Console.Write(make_cuts(arr, N, K));
}
}
|
Javascript
<script>
function make_cuts(arr, n, K)
{
var ans = 0;
var poss = [];
var ce = 0;
var co = 0;
var x;
for (x = 0; x < n - 1; x++) {
if (arr[x] % 2 == 0)
ce++;
else
co++;
if (ce == co && co > 0
&& ce > 0) {
poss.push(
Math.abs(arr[x]
- arr[x + 1]));
}
}
poss.sort();
var i;
for (i=0;i<poss.length;i++){
if (K >= poss[i]) {
ans++;
K -= poss[i];
}
else
break ;
}
return ans;
}
var N = 6;
var K = 4;
var arr = [1, 2, 5, 10, 15, 20];
document.write(make_cuts(arr, N, K));
</script>
|
Time Complexity: O(N log(N))
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...