Open In App

Find maximum element after K increments

Last Updated : 24 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N, in one operation you can increase arr[i] by 1 if arr[i] <= arr[i+1]. The task is to find the maximum value of the array if you can perform the above operation K number of times.

Examples:

Input: n = 3, K = 4, arr[] = {2, 4, 4}
Output: 5
Explanation: The maximum element we can have in arr[] is 5 after the following operations:

  • Increment arr[1] by 1, arr[] = {2, 5, 4}
  • Increment arr[2] by 1, arr[] = {2, 5, 5}
  • Increment arr[1] by 1, arr[] = {2, 6, 5}
  • Increment arr[2] by 1, arr[] = {2, 6, 6}

Input: n = 5, K = 6, arr[] = {1, 3, 4, 5, 1}
Output: 7
Explanation: The maximum element we can have in arr[] is 7 after the following operations:

  • Increment arr[2] by 1, arr[] = {1, 3, 5, 5, 1}
  • Increment arr[2] by 1, arr[] = {1, 3, 6, 5, 1}
  • Increment arr[1] by 1, arr[] = {1, 4, 6, 5, 1}
  • Increment arr[1] by 1, arr[] = {1, 5, 6, 5, 1}
  • Increment arr[1] by 1, arr[] = {1, 6, 6, 5, 1}
  • Increment arr[1] by 1, arr[] = {1, 7, 6, 5, 1}

Approach: To solve the problem, follow the below idea:

The idea is to use binary search to solve the problem. The reason binary search is suitable here is because of the property of monotonicity in the problem. If it’s possible to make all elements at least mid using K operations, then it’s also possible to make all elements at least mid – 1, mid – 2, etc., using k operations. This property allows us to use binary search to efficiently find the maximum mid for which it’s possible to make all elements at least mid.

For binary search, Initialize the lower bound to 0 and the upper bound to the maximum element in the array plus the number of operations. Performs a binary search between the lower and upper bounds. For each mid-value, check if it’s possible to make all elements at least mid using the given number of operations.

For each element in the array, calculates the minimum number of operations needed to make that element at least mid. If the total number of operations used is less than or equal to K, it’s possible to make all elements at least mid.

If it’s possible to make all elements at least mid, updates the answer to mid and moves the lower bound to mid + 1. Otherwise, it moves the upper bound to mid – 1.

Step-by-step algorithm:

  • Set lowerBound to 0 and upperBound to max array element + K.
  • While lowerBound <= upperBound:
    • Calculate mid = (lowerBound and upperBound)/2
    • For each array element:
      • Check if the minimum needed value for the current element is less than or equal to the original value (arr[j]).
      • If not, update the operationsUsed by the difference between the minimum needed and the original value.
      • Update the minNeeded for the next element based on the current minimum needed and decrement by 1.
      • Check if the total operationsUsed is within the limit of K.
      • If yes, set isPossible to true.
    • Check if isPossible = true, update answer = mid and lowerBound = mid + 1
    • Otherwise, update upperBound = mid – 1
  • Return the final answer after binary search.

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Define the type long long as ll for convenience
typedef long long ll;
 
// Function to find the maximum value of the array
ll findMaxValue(ll n, ll k, vector<ll>& arr)
{
 
    // Variables to store the lower and upper bounds and the
    // answer
    ll lowerBound = 0,
       upperBound
       = *max_element(arr.begin(), arr.end()) + k,
       answer = 0;
 
    // Binary search for the answer
    while (lowerBound <= upperBound) {
        ll mid = (lowerBound + upperBound) / 2;
        bool isPossible = false;
 
        // Try to make all elements at least mid
        for (int i = 0; i < n; i++) {
            vector<ll> minNeeded(n);
            minNeeded[i] = mid;
 
            ll operationsUsed = 0;
            for (int j = i; j < n; j++) {
                if (minNeeded[j] <= arr[j])
                    break;
 
                if (j + 1 >= n) {
                    operationsUsed = k + 1;
                    break;
                }
 
                operationsUsed += minNeeded[j] - arr[j];
                minNeeded[j + 1]
                    = max(0LL, minNeeded[j] - 1);
            }
 
            if (operationsUsed <= k)
                isPossible = true;
        }
 
        // Update the answer and the bounds
        if (isPossible) {
            answer = mid;
            lowerBound = mid + 1;
        }
        else {
            upperBound = mid - 1;
        }
    }
 
    return answer;
}
 
int main()
{
 
    // Variables to store the input numbers and the array
    ll n = 3, k = 4;
    vector<ll> arr = { 2, 4, 4 };
 
    // Print the maximum value of the array
    cout << findMaxValue(n, k, arr);
}


Java




/*code by Flutterfly */
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
 
public class Main {
 
    // Function to find the maximum value of the array
    static long findMaxValue(int n, long k, ArrayList<Long> arr) {
 
        // Variables to store the lower and upper bounds and the answer
        long lowerBound = 0;
        long upperBound = Collections.max(arr) + k;
        long answer = 0;
 
        // Binary search for the answer
        while (lowerBound <= upperBound) {
            long mid = (lowerBound + upperBound) / 2;
            boolean isPossible = false;
 
            // Try to make all elements at least mid
            for (int i = 0; i < n; i++) {
                ArrayList<Long> minNeeded = new ArrayList<>(Collections.nCopies(n, 0L));
                minNeeded.set(i, mid);
 
                long operationsUsed = 0;
                for (int j = i; j < n; j++) {
                    if (minNeeded.get(j) <= arr.get(j))
                        break;
 
                    if (j + 1 >= n) {
                        operationsUsed = k + 1;
                        break;
                    }
 
                    operationsUsed += minNeeded.get(j) - arr.get(j);
                    minNeeded.set(j + 1, Math.max(0, minNeeded.get(j) - 1));
                }
 
                if (operationsUsed <= k)
                    isPossible = true;
            }
 
            // Update the answer and the bounds
            if (isPossible) {
                answer = mid;
                lowerBound = mid + 1;
            } else {
                upperBound = mid - 1;
            }
        }
 
        return answer;
    }
 
    public static void main(String[] args) {
 
        // Variables to store the input numbers and the array
        int n = 3;
        long k = 4;
        ArrayList<Long> arr = new ArrayList<>(Arrays.asList(2L, 4L, 4L));
 
        // Print the maximum value of the array
        System.out.println(findMaxValue(n, k, arr));
    }
}


Python3




# code by Flutterfly
def find_max_value(n, k, arr):
    # Variables to store the lower and upper bounds and the answer
    lower_bound = 0
    upper_bound = max(arr) + k
    answer = 0
 
    # Binary search for the answer
    while lower_bound <= upper_bound:
        mid = (lower_bound + upper_bound) // 2
        is_possible = False
 
        # Try to make all elements at least mid
        for i in range(n):
            min_needed = [0] * n
            min_needed[i] = mid
 
            operations_used = 0
            for j in range(i, n):
                if min_needed[j] <= arr[j]:
                    break
 
                if j + 1 >= n:
                    operations_used = k + 1
                    break
 
                operations_used += min_needed[j] - arr[j]
                min_needed[j + 1] = max(0, min_needed[j] - 1)
 
            if operations_used <= k:
                is_possible = True
 
        # Update the answer and the bounds
        if is_possible:
            answer = mid
            lower_bound = mid + 1
        else:
            upper_bound = mid - 1
 
    return answer
 
# Variables to store the input numbers and the array
n = 3
k = 4
arr = [2, 4, 4]
 
# Print the maximum value of the array
print(find_max_value(n, k, arr))


C#




//code by Flutterfly
using System;
using System.Linq;
 
class Program
{
    static int FindMaxValue(int n, int k, int[] arr)
    {
        // Variables to store the lower and upper bounds and the answer
        int lowerBound = 0;
        int upperBound = arr.Max() + k;
        int answer = 0;
 
        // Binary search for the answer
        while (lowerBound <= upperBound)
        {
            int mid = (lowerBound + upperBound) / 2;
            bool isPossible = false;
 
            // Try to make all elements at least mid
            for (int i = 0; i < n; i++)
            {
                int[] minNeeded = new int[n];
                minNeeded[i] = mid;
 
                int operationsUsed = 0;
                for (int j = i; j < n; j++)
                {
                    if (minNeeded[j] <= arr[j])
                        break;
 
                    if (j + 1 >= n)
                    {
                        operationsUsed = k + 1;
                        break;
                    }
 
                    operationsUsed += minNeeded[j] - arr[j];
                    minNeeded[j + 1] = Math.Max(0, minNeeded[j] - 1);
                }
 
                if (operationsUsed <= k)
                    isPossible = true;
            }
 
            // Update the answer and the bounds
            if (isPossible)
            {
                answer = mid;
                lowerBound = mid + 1;
            }
            else
            {
                upperBound = mid - 1;
            }
        }
 
        return answer;
    }
 
    static void Main()
    {
        // Variables to store the input numbers and the array
        int n = 3;
        int k = 4;
        int[] arr = { 2, 4, 4 };
 
        // Print the maximum value of the array
        Console.WriteLine(FindMaxValue(n, k, arr));
    }
}


Javascript




//code by flutterfly
function findMaxValue(n, k, arr) {
    // Variables to store the lower and upper bounds and the answer
    let lowerBound = 0;
    let upperBound = Math.max(...arr) + k;
    let answer = 0;
 
    // Binary search for the answer
    while (lowerBound <= upperBound) {
        let mid = Math.floor((lowerBound + upperBound) / 2);
        let isPossible = false;
 
        // Try to make all elements at least mid
        for (let i = 0; i < n; i++) {
            let minNeeded = Array(n).fill(0);
            minNeeded[i] = mid;
 
            let operationsUsed = 0;
            for (let j = i; j < n; j++) {
                if (minNeeded[j] <= arr[j]) {
                    break;
                }
 
                if (j + 1 >= n) {
                    operationsUsed = k + 1;
                    break;
                }
 
                operationsUsed += minNeeded[j] - arr[j];
                minNeeded[j + 1] = Math.max(0, minNeeded[j] - 1);
            }
 
            if (operationsUsed <= k) {
                isPossible = true;
            }
        }
 
        // Update the answer and the bounds
        if (isPossible) {
            answer = mid;
            lowerBound = mid + 1;
        } else {
            upperBound = mid - 1;
        }
    }
 
    return answer;
}
 
// Variables to store the input numbers and the array
let n = 3;
let k = 4;
let arr = [2, 4, 4];
 
// Print the maximum value of the array
console.log(findMaxValue(n, k, arr));


Output

5

Time complexity: O(N^2 log M), where N is the size of the array and M is the range of possible values
Auxiliary space: O(N).



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads