Given array A[] (1 <= A[i] <= 108) of size N (2 <= N <= 103) and integer K (1 <= K <= 108), the task is to find the largest element of the array after performing the given operation at most K times, in one operation choose i from 1 to N – 1 such that A[i] <= A[i + 1] and then increase A[i] by 1.
Examples:
Input: A[] = {1, 3, 3}, K = 4
Output: 4
Explanation:
- Choose i = 1, Array becomes A[] = {2, 3, 3}
- Choose i = 2, Array becomes A[] = {2, 4, 3}
- Choose i = 1, Array becomes A[] = {3, 4, 3}
- Choose i = 1, Array becomes A[] = {4, 4, 3}
The largest element of the above array after performing given operations optimally at most K times is 4.
Input: A[] = {1, 3, 4, 5, 1}, K = 6
Output: 7
Explanation:
- Choose i = 3, Array becomes A[] = {1, 3, 5, 5, 1}
- Choose i = 3, Array becomes A[] = {1, 3, 6, 5, 1}
- Choose i = 2, Array becomes A[] = {1, 4, 6, 5, 1}
- Choose i = 2, Array becomes A[] = {1, 5, 6, 5, 1}
- Choose i = 2, Array becomes A[] = {1, 6, 6, 5, 1}
- Choose i = 2, Array becomes A[] = {1, 7, 6, 5, 1}
The largest element of the above array after performing given operations optimally at most K times is 7.
Naïve Approach: The basic way to solve the problem is as follows:
Check For every value from 1 to maxArrayElement(A[]) + K is possible or not. This can be done for each value by checking if it is possible to make A[i] equal to the value that we are checking for in O(N2) for each array element.
Time Complexity: O(N3)
Auxiliary Space: O(1)
Efficient Approach: To solve the problem follow the below idea:
Binary Search can be used to solve this problem and the range of binary search will be 1 to maxArrayElement(A[]) + K. f(N) is monotonic function represents whether N can be maximum value of array after performing at most K operations. it is of the form TTTTTTFFFFFFF. we have to find when the last time function was true using Binary Search.
Below are the steps for the above approach:
- Set low and high range of binary serach.
- isMaximum(mid) function used to check whether mid can be largest value of array after performing given operations. For each i from 1 to N – 1 it checks the number of operations required to make it greater than equal to mid (A[i] >= mid). if number of operations are less than equal to operations available (that is K) then return true else return false.
-
Run while loop till high and low are not equal.
- In while loop find middle element and store it in mid variable.
- Check if that mid can be maximum value of array using isMaximum() function. If it is true then set low = mid else high = mid – 1.
- After loop ends if isMaximum() true for high then return high else return low.
Below is the implementation of the above approach:
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to check if given number can be // made after performing given operations bool isMaximum( int mid, int A[], int N, int K)
{ // if last element of array greater than
// equal to mid return 1
if (A[N - 1] >= mid)
return 1;
// Define variable that tracks min number
// of operations to make array
// element equal to mid
int minOperations = 1e9;
for ( int i = 0; i < N - 1; i++) {
// Number of operations for each A[i]
int noOfOperations = 0;
// All elements from i should be set to
// mid, mid - 1, mid - 2, mid - 3,
// mid - 4, .....
for ( int j = i, offset = 0; j < N; j++, offset++) {
// If A[j] is less than required
// number that is mid - offset
// (mid, mid - 1, mid - 2, ......)
// we cannot change last element
// if last element have to be set
// to mid - offset return large
// invalid number
if ((mid - offset) > A[j])
noOfOperations
+= ((mid - offset) - A[j])
+ ((j == N - 1) ? 2e8 : 0);
// If (mid - offset) <= A[j] already
// satisfied then break out of loop
else
break ;
}
// Updating min number of operations
minOperations = min(minOperations, noOfOperations);
}
// Return true if minimum number of
// operations required to make largest
// element of array equal to mid is less
// than equal to operations available
return minOperations <= K;
} // Function to find Largest element after // performing given operations at most K times int findLargestElement( int A[], int N, int K)
{ // Range of binary search
int low = 1, high = *max_element(A, A + N) + K;
// Running loop till high
// is not equal to low
while (high - low > 1) {
// mid is average of low and high
int mid = (low + high) / 2;
// Checking test function
if (isMaximum(mid, A, N, K)) {
low = mid;
}
else {
high = mid - 1;
}
}
// Checking whether high can be answer
if (isMaximum(high, A, N, K))
return high;
// If not then it is low
else
return low;
} // Driver Code int32_t main() { // Input 1
int K = 4;
int A[] = { 1, 3, 3 }, N = 3;
// Function Call
cout << findLargestElement(A, N, K) << endl;
// Input 2
int K1 = 6;
int A1[] = { 1, 3, 4, 5, 1 }, N1 = 5;
// Function Call
cout << findLargestElement(A1, N1, K1) << endl;
return 0;
} |
import java.util.Arrays;
public class Main {
// Function to check if given number can be
// made after performing given operations
static boolean isMaximum( int mid, int [] A, int N, int K) {
// if last element of array greater than
// equal to mid return true
if (A[N - 1 ] >= mid)
return true ;
// Define variable that tracks min number
// of operations to make array
// element equal to mid
int minOperations = 1_000_000_000;
for ( int i = 0 ; i < N - 1 ; i++) {
// Number of operations for each A[i]
int noOfOperations = 0 ;
// All elements from i should be set to
// mid, mid - 1, mid - 2, mid - 3,
// mid - 4, .....
for ( int j = i, offset = 0 ; j < N; j++, offset++) {
// If A[j] is less than required
// number that is mid - offset
// (mid, mid - 1, mid - 2, ......)
// we cannot change last element
// if the last element has to be set
// to mid - offset return a large
// invalid number
if ((mid - offset) > A[j])
noOfOperations += ((mid - offset) - A[j]) + ((j == N - 1 ) ? 200_000_000 : 0 );
// If (mid - offset) <= A[j] already
// satisfied then break out of loop
else
break ;
}
// Updating min number of operations
minOperations = Math.min(minOperations, noOfOperations);
}
// Return true if minimum number of
// operations required to make largest
// element of the array equal to mid is less
// than or equal to operations available
return minOperations <= K;
}
// Function to find Largest element after
// performing given operations at most K times
static int findLargestElement( int [] A, int N, int K) {
// Range of binary search
int low = 1 , high = Arrays.stream(A).max().getAsInt() + K;
// Running loop until high
// is not equal to low
while (high - low > 1 ) {
// mid is the average of low and high
int mid = (low + high) / 2 ;
// Checking the test function
if (isMaximum(mid, A, N, K)) {
low = mid;
} else {
high = mid - 1 ;
}
}
// Checking whether high can be the answer
if (isMaximum(high, A, N, K))
return high;
// If not then it is low
else
return low;
}
// Driver Code
public static void main(String[] args) {
// Input 1
int K = 4 ;
int [] A = { 1 , 3 , 3 };
int N = 3 ;
// Function Call
System.out.println(findLargestElement(A, N, K));
// Input 2
int K1 = 6 ;
int [] A1 = { 1 , 3 , 4 , 5 , 1 };
int N1 = 5 ;
// Function Call
System.out.println(findLargestElement(A1, N1, K1));
}
} //This code is Contributed by chinmaya121221 |
# Function to check if given number can be # made after performing given operations def is_maximum(mid, A, N, K):
if A[N - 1 ] > = mid:
return True
min_operations = float ( 'inf' )
for i in range (N - 1 ):
no_of_operations = 0
for j in range (i, N):
offset = j - i
if mid - offset > A[j]:
no_of_operations + = (mid - offset - A[j]) + ( 2e8 if j = = N - 1 else 0 )
else :
break
min_operations = min (min_operations, no_of_operations)
return min_operations < = K
# Function to find Largest element after # performing given operations at most K times def find_largest_element(A, N, K):
low, high = 1 , max (A) + K
while high - low > 1 :
mid = (low + high) / / 2
if is_maximum(mid, A, N, K):
low = mid
else :
high = mid - 1
if is_maximum(high, A, N, K):
return high
else :
return low
# Driver Code if __name__ = = "__main__" :
# Input 1
K = 4
A = [ 1 , 3 , 3 ]
N = 3
result = find_largest_element(A, N, K)
print (result)
# Input 2
K1 = 6
A1 = [ 1 , 3 , 4 , 5 , 1 ]
N1 = 5
result1 = find_largest_element(A1, N1, K1)
print (result1)
|
using System;
using System.Linq;
class Program
{ // Function to check if given number can be
// made after performing given operations
static bool IsMaximum( int mid, int [] A, int N, int K)
{
// if last element of array greater than
// equal to mid return 1
if (A[N - 1] >= mid)
return true ;
// Define variable that tracks min number
// of operations to make array
// element equal to mid
int minOperations = int .MaxValue;
for ( int i = 0; i < N - 1; i++)
{
// Number of operations for each A[i]
int noOfOperations = 0;
// All elements from i should be set to
// mid, mid - 1, mid - 2, mid - 3,
// mid - 4, .....
for ( int j = i, offset = 0; j < N; j++, offset++)
{
// If A[j] is less than required
// number that is mid - offset
// (mid, mid - 1, mid - 2, ......)
// we cannot change last element
// if last element have to be set
// to mid - offset return large
// invalid number
if ((mid - offset) > A[j])
noOfOperations += ((mid - offset) - A[j]) + ((j == N - 1) ? 200000000 : 0);
// If (mid - offset) <= A[j] already
// satisfied then break out of loop
else
break ;
}
// Updating min number of operations
minOperations = Math.Min(minOperations, noOfOperations);
}
// Return true if minimum number of
// operations required to make largest
// element of array equal to mid is less
// than equal to operations available
return minOperations <= K;
}
// Function to find Largest element after
// performing given operations at most K times
static int FindLargestElement( int [] A, int N, int K)
{
// Range of binary search
int low = 1, high = A.Max() + K;
// Running loop till high
// is not equal to low
while (high - low > 1)
{
// mid is average of low and high
int mid = (low + high) / 2;
// Checking test function
if (IsMaximum(mid, A, N, K))
{
low = mid;
}
else
{
high = mid - 1;
}
}
// Checking whether high can be answer
if (IsMaximum(high, A, N, K))
return high;
// If not then it is low
else
return low;
}
// Driver Code
static void Main( string [] args)
{
int K = 4;
int [] A = { 1, 3, 3 };
int N = 3;
Console.WriteLine(FindLargestElement(A, N, K));
int K1 = 6;
int [] A1 = { 1, 3, 4, 5, 1 };
int N1 = 5;
Console.WriteLine(FindLargestElement(A1, N1, K1));
}
} |
// Function to check if given number can be // made after performing given operations function isMaximum(mid, A, N, K) {
// If the last element of the array is greater than or equal to mid, return true
if (A[N - 1] >= mid) {
return true ;
}
// Define a variable to track the minimum number of operations to make array elements equal to mid
let minOperations = 1e9;
for (let i = 0; i < N - 1; i++) {
// Number of operations for each A[i]
let noOfOperations = 0;
// All elements from i should be set to mid, mid - 1, mid - 2, mid - 3, ...
for (let j = i, offset = 0; j < N; j++, offset++) {
// If A[j] is less than the required number (mid - offset), we cannot change the last element
// If the last element has to be set to mid - offset, return a large invalid number
if (mid - offset > A[j]) {
noOfOperations += (mid - offset - A[j]) + ((j === N - 1) ? 2e8 : 0);
} else {
break ;
}
}
// Update the minimum number of operations
minOperations = Math.min(minOperations, noOfOperations);
}
// Return true if the minimum number of operations required to make the largest element of the array equal to mid is less than or equal to the available operations (K)
return minOperations <= K;
} // Function to find the largest element after // performing given operations at most K times function findLargestElement(A, N, K) {
// Range of binary search
let low = 1;
let high = Math.max(...A) + K;
// Running loop until high is not equal to low
while (high - low > 1) {
// Calculate mid as the average of low and high
let mid = Math.floor((low + high) / 2);
// Check with the test function
if (isMaximum(mid, A, N, K)) {
low = mid;
} else {
high = mid - 1;
}
}
// Check if high can be the answer
if (isMaximum(high, A, N, K)) {
return high;
} else {
return low;
}
} // Driver Code // Input 1 const K = 4; const A = [1, 3, 3]; const N = 3; // Function Call console.log(findLargestElement(A, N, K)); // Input 2 const K1 = 6; const A1 = [1, 3, 4, 5, 1]; const N1 = 5; // Function Call console.log(findLargestElement(A1, N1, K1)); |
4 7
Time Complexity: O(N2logN)
Auxiliary Space: O(1)