Longest subarray whose elements can be made equal by maximum K increments
Given an array arr[] of positive integers of size N and a positive integer K, the task is to find the maximum possible length of a subarray which can be made equal by adding some integer value to each element of the sub-array such that the sum of the added elements does not exceed K.
Examples:
Input: N = 5, arr[] = {1, 4, 9, 3, 6}, K = 9
Output: 3
Explanation:
{1, 4} : {1+3, 4} = {4, 4}
{4, 9} : {4+5, 9} = {9, 9}
{3, 6} : {3+3, 6} = {6, 6}
{9, 3, 6} : {9, 3+6, 6+3} = {9, 9, 9}
Hence, the maximum length of such a subarray is 3.
Input: N = 6, arr[] = {2, 4, 7, 3, 8, 5}, K = 10
Output: 4
Approach: This problem can be solved by using dynamic programming.
- Initialize:
- dp[]: Stores the sum of elements that are added to the subarray.
- deque: Stores the indices of the maximum element for each subarray.
- pos: Index of the current position of the subarray.
- ans: Length of the maximum subarray.
- mx: Maximum element of a subarray
- pre: Previous index of the current subarray.
- Traverse the array and check if the deque is empty or not. If yes, then update the maximum element and the index of the maximum element along with the indices of pre and pos.
- Check if the currently added element is greater than K. If yes, then remove it from dp[] array and update the indices of pos and pre.
- Finally, update the maximum length of the valid sub-array.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int validSubArrLength( int arr[],
int N, int K)
{
int dp[N + 1];
int pos = 0;
int ans = 0;
int mx = 0;
int pre = 0;
deque< int > q;
for ( int i = 0; i < N; i++) {
while (!q.empty()
&& arr[q.back()] < arr[i])
q.pop_back();
q.push_back(i);
if (i == 0) {
mx = arr[i];
dp[i] = arr[i];
}
else if (mx <= arr[i]) {
dp[i] = dp[i - 1] + arr[i];
mx = arr[i];
}
else {
dp[i] = dp[i - 1] + arr[i];
}
if (pre == 0)
pos = 0;
else
pos = pre - 1;
while ((i - pre + 1) * mx
- (dp[i] - dp[pos])
> K
&& pre < i) {
pos = pre;
pre++;
while (!q.empty()
&& q.front() < pre
&& pre < i) {
q.pop_front();
mx = arr[q.front()];
}
}
ans = max(ans, i - pre + 1);
}
return ans;
}
int main()
{
int N = 6;
int K = 8;
int arr[] = { 2, 7, 1, 3, 4, 5 };
cout << validSubArrLength(arr, N, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int validSubArrLength( int arr[],
int N, int K)
{
int []dp = new int [N + 1 ];
int pos = 0 ;
int ans = 0 ;
int mx = 0 ;
int pre = 0 ;
Deque<Integer> q = new LinkedList<>();
for ( int i = 0 ; i < N; i++)
{
while (!q.isEmpty() &&
arr[q.getLast()] < arr[i])
q.removeLast();
q.add(i);
if (i == 0 )
{
mx = arr[i];
dp[i] = arr[i];
}
else if (mx <= arr[i])
{
dp[i] = dp[i - 1 ] + arr[i];
mx = arr[i];
}
else
{
dp[i] = dp[i - 1 ] + arr[i];
}
if (pre == 0 )
pos = 0 ;
else
pos = pre - 1 ;
while ((i - pre + 1 ) * mx -
(dp[i] - dp[pos]) > K && pre < i)
{
pos = pre;
pre++;
while (!q.isEmpty() &&
q.peek() < pre && pre < i)
{
q.removeFirst();
mx = arr[q.peek()];
}
}
ans = Math.max(ans, i - pre + 1 );
}
return ans;
}
public static void main(String[] args)
{
int N = 6 ;
int K = 8 ;
int arr[] = { 2 , 7 , 1 , 3 , 4 , 5 };
System.out.print(validSubArrLength(arr, N, K));
}
}
|
Python3
def validSubArrLength(arr, N, K):
dp = [ 0 for i in range (N + 1 )]
pos = 0
ans = 0
mx = 0
pre = 0
q = []
for i in range (N):
while ( len (q) and arr[ len (q) - 1 ] < arr[i]):
q.remove(q[ len (q) - 1 ])
q.append(i)
if (i = = 0 ):
mx = arr[i]
dp[i] = arr[i]
elif (mx < = arr[i]):
dp[i] = dp[i - 1 ] + arr[i]
mx = arr[i]
else :
dp[i] = dp[i - 1 ] + arr[i]
if (pre = = 0 ):
pos = 0
else :
pos = pre - 1
while ((i - pre + 1 ) *
mx - (dp[i] - dp[pos]) > K and
pre < i):
pos = pre
pre + = 1
while ( len (q) and
q[ 0 ] < pre and
pre < i):
q.remove(q[ 0 ])
mx = arr[q[ 0 ]]
ans = max (ans, i - pre + 1 )
return ans
if __name__ = = '__main__' :
N = 6
K = 8
arr = [ 2 , 7 , 1 , 3 , 4 , 5 ]
print (validSubArrLength(arr, N, K))
|
Javascript
<script>
function validSubArrLength(arr, N, K)
{
var dp = Array(N+1);
var pos = 0;
var ans = 0;
var mx = 0;
var pre = 0;
var q = [];
for ( var i = 0; i < N; i++) {
while (q.length!=0
&& arr[q[q.length-1]] < arr[i])
q.pop();
q.push(i);
if (i == 0) {
mx = arr[i];
dp[i] = arr[i];
}
else if (mx <= arr[i]) {
dp[i] = dp[i - 1] + arr[i];
mx = arr[i];
}
else {
dp[i] = dp[i - 1] + arr[i];
}
if (pre == 0)
pos = 0;
else
pos = pre - 1;
while ((i - pre + 1) * mx
- (dp[i] - dp[pos])
> K
&& pre < i) {
pos = pre;
pre++;
while (q.length!=0
&& q[0] < pre
&& pre < i) {
q.shift();
mx = arr[q[0]];
}
}
ans = Math.max(ans, i - pre + 1);
}
return ans;
}
var N = 6;
var K = 8;
var arr = [2, 7, 1, 3, 4, 5];
document.write( validSubArrLength(arr, N, K));
</script>
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
static int validSubArrLength( int [] arr, int N, int K)
{
int [] dp = new int [N + 1];
int pos = 0;
int ans = 0;
int mx = 0;
int pre = 0;
List< int > q = new List< int >();
for ( int i = 0 ; i < N ; i++)
{
while (q.Count > 0 && arr[q[q.Count - 1]] < arr[i]){
q.RemoveAt(q.Count - 1);
}
q.Add(i);
if (i == 0)
{
mx = arr[i];
dp[i] = arr[i];
}
else if (mx <= arr[i])
{
dp[i] = dp[i - 1] + arr[i];
mx = arr[i];
}
else
{
dp[i] = dp[i - 1] + arr[i];
}
if (pre == 0)
pos = 0;
else
pos = pre - 1;
while ((i - pre + 1) * mx - (dp[i] - dp[pos]) > K && pre < i)
{
pos = pre;
pre++;
while (q.Count > 0 && q[0] < pre && pre < i)
{
q.RemoveAt(0);
mx = arr[q[0]];
}
}
ans = Math.Max(ans, i - pre + 1);
}
return ans;
}
public static void Main( string [] args){
int N = 6;
int K = 8;
int [] arr = new int []{ 2, 7, 1, 3, 4, 5 };
Console.WriteLine(validSubArrLength(arr, N, K));
}
}
|
Time Complexity: O(N2)
Auxiliary Space Complexity: O(N)
Last Updated :
22 Jun, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...