Longest Subarray whose Elements can be Made Equal by Maximum K Increments


In this problem, we will find the length of the longest subarray so that we can make all subarray elements the same by adding some positive integer values, and the sum of added numbers to each element shouldn’t increase than K.

The naïve approach is to find the cost of making all elements the same in each subarray of the given array. Finally, consider the length of the subarray whose cost is less than K and the length is maximum.

However, we will use the queue data structure to solve the problem efficiently.

Problem statement − We have given an array of size N containing the integers. Also, we have given a K positive integer. The task is to find the length of the longest subarray so that we can make all elements of subarray by adding some numbers to each element of the subarray. Also, the sum of added numbers should not increase than the K.

Sample examples

Input

K = 6; arr[] = {2, 3, 5, 15, 3, 8};

Output

3

Explanation − We can take the {2, 3, 5} subarray. So, the total cost to make all elements of the subarray equal is the sum of {3, 2, 0}, which is 5.

Input

K = 2; arr[] = {2, 2, 2, 2, 2, 2}

Output

6

Explanation − All elements of the given array are the same. So, we can choose the given array as a subarray.

Input

K = 3; arr[] = {4, 5, 4, 4, 5, 1, 2, 3, 3, 3};

Output

5

Explanation − Here, we can choose {4, 5, 4, 4, 5} or {1, 2, 3, 3, 3} subarray, as both arrays have the same length and cost equal to make all numbers is equal to 3.

Approach 1

In this approach, we will traverse all subarrays of the given array. Also, we will keep track of the maximum element and sum of elements of the current subarray. If the cost for making all elements of the subarray equal is less than K, and its length is less than the max_len, we will update the max_len.

Algorithm

Step 1 − Define the max_len and initialize with the 0

Step 2 − Start traversing the array using the loop. In the loop, define the maxEle and sum variables, and initialize them with 0.

Step 3 − Use another nested loop to traverse the array from the Pth index, as the subarray starts from the Pth index.

Step 4 − Update the maxEle if it is smaller than the current array element. Also, add an array element to the ‘sum’ variable.

Step 5 − Now, we need to equal all elements of the subarray equal to maxEle, and the length of the subarray is q − p + 1. So, if maxEle * (q − p + 1) is less than or equal to K, update the max_len variable if it is less than q − p + 1.

Step 6 − Return max_len value.

Example

#include <bits/stdc++.h>
using namespace std;

int maxSubArrayLength(int arr[], int N, int K) {
    int max_len = 0;
    // Traverse all subarrays of the given array
    for (int p = 0; p < N; p++) {
        int maxEle = 0;
        int sum = 0;
        for (int q = p; q < N; q++) {
            // Update maximum element
            maxEle = max(maxEle, arr[q]);
            sum += arr[q];
            // Check whether we can make all elements of the array equal to maxEle
            if (maxEle * (q - p + 1) <= sum + K) {
                // Update maximum length
                max_len = max(max_len, q - p + 1);
            }
        }
    }
    return max_len;
}
int main() { 
    int N = 6;
    int K = 6;
    int arr[] = {2, 3, 5, 15, 3, 8};
    cout << "The maximum length of subarray such that we can make all elements of it same is " << maxSubArrayLength(arr, N, K);
    return 0;
}

Output

The maximum length of subarray such that we can make all elements of it same is 3

Time complexity − O(N*N) to traverse all subarrays.

Space complexity − O(1)

Approach 2

Algorithm

Step 1 − Define the deque data structure named ‘maxQueue’ to store the index of maximum element of the subarray.

Step 2 − Define the pref_sum[] array to store the prefix sum and initialize the 0th index with the 0.

Step 3 − Traverse the array and store the prefix sum of elements into the pref_sum[] array.

Step 4 − Initialize the ‘left’ and ‘max_len’ with 0, pointing to the left index of the array and tracking the maximum length of the subarray. Also, define the max_ele to store the maximum element of the subarray.

Step 5 − Again, start traversing the array.

Step 5.1 − In the for loop, use the while loop to remove the elements from the queue until either queue is empty or the element at the last index of the queue is smaller than the arr[p].

Step 5.2 − Insert the p into the queue.

Step 5.3 − If p is 0, Initialize the max_ele with arr[p]. Otherwise, update the max_ele only if it is less than arr[p].

Step 5.4 − Now use the while loop to make iterations until either (p − left + 1) * max_ele − (pref_sum[p + 1] − pref_sum[left] is greater than K, or the ‘left’ point is less than p.

Step 5.4.1 − In the while loop, increment the ‘left’ by 1 in each iteration.

Step 5.4.2 − Also, remove the elements from the queue which are less than ‘left’.

Step 5.5 − Update the max_len with the p − left + 1 if it is greater than the max_len.

Step 6 − Return max_len value.

Example

#include <bits/stdc++.h>
using namespace std;

int maxSubArrayLength(int arr[], int N, int K) {
    // Queue to store elements
    deque<int> maxQueue;
    // To store prefix sum
    int pref_sum[N + 1];
    pref_sum[0] = 0;
    // Calculating the prefix sum
    for (int p = 1; p <= N; p++) {
        pref_sum[p] = pref_sum[p - 1] + arr[p - 1];
    }
    // Start point of sub-array
    int left = 0;
    // For tracking the maximum element of the sub-array
    int max_ele;
    // To store the answer
    int max_len = 0;
    for (int p = 0; p < N; p++) {
        // Remove all smaller elements from the back to make the current element as maximum
        while (!maxQueue.empty() && arr[maxQueue.back()] < arr[p]) {
            maxQueue.pop_back();
        }
        // Insert current index
        maxQueue.push_back(p);
        // Update maximum element
        if (p == 0) {
            max_ele = arr[p];
        } else 
            max_ele = max(max_ele, arr[p]);
        // Calculating the cost to make all elements equal to the maximum
        while ((p - left + 1) * max_ele - (pref_sum[p + 1] - pref_sum[left]) > K && p > left) {
            // Increment starting point
            left++;
            // Remove the element from the current window
            while (!maxQueue.empty() && maxQueue.front() < left && left < p) {
                maxQueue.pop_front();
                max_ele = arr[maxQueue.front()];
            }
        }
        // Update maximum size
        max_len = max(max_len, p - left + 1);
    }
    return max_len;
}
int main() {
    int N = 6;
    int K = 6;
    int arr[] = {2, 3, 5, 15, 3, 8};
    cout << "The maximum length of subarray such that we can make all elements of it same is " << maxSubArrayLength(arr, N, K);
    return 0;
}

Output

The maximum length of subarray such that we can make all elements of it same is 3

Time complexity − O(N^2), as we use nested loops.

Space complexity − O(N), as we use a queue.

Both approaches have the same time complexity in the worst case. However, the second approach is efficient when we need to perform the given operation with the regular array.

Updated on: 02-Aug-2023

207 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements