Given an array arr[] of size N. The task is to maximize the minimum value of the array after performing given operations. In an operation, value x can be chosen and
- A value 3 * x can be subtracted from the arr[i] element.
- A value x is added to arr[i-1]. and
- A value of 2 * x can be added to arr[i-2].
Find the maximum possible minimum element of the array after any such operations.
Examples:
Input: arr[] = {1, 2, 3, 4, 5, 6}
Output: 3
Explanation: The last element is chosen and x =1 can be chosen.
So 3*x gets subtracted from arr[i] and x gets added to arr[i-1] and 2*x to arr[i-2] so the array becomes {1, 2, 3, 6, 6, 3}
In the 4th index x =1 can be chosen and now the array becomes {1, 2, 5, 7, 3, 3}.
In the 3rd index x = 1 can be chosen and now the array becomes {1, 4, 6, 4, 3, 3}.
In the 2nd index again x =1 can be chosen and now the array becomes {3, 4, 3, 4, 3, 3, 3}.
Hence the maximum possible minimum value is 3.Input: arr[] = {9, 13, 167}
Output: 51
Naive Approach: This problem can be solved by checking for the possibility of maximum possible minimum value from [1, max(array)] by performing the operations from the end of the array.
Time Complexity: O(N2)
Space Complexity: O(1)
Efficient Approach: The efficient approach of this problem is based on Binary Search. Since it is based on maximizing the minimum value so by applying the binary search in the range [1, max(array)] and checking if mid is possible as a minimum element by performing the operations on the array such that every element is >=mid. Follow the steps below to solve the given problem:
- Initialize f = 1 and l = maximum element of the array and the res as INT_MIN.
- Perform binary search while f<=l
- Check if mid can be the minimum element by performing operations in the is_possible_min() function.
- In the is_possible_min() function
- Traverse from the end of the array (N-1) till index 2 and check if arr[i]<mid if it true return 0.
- Else find the extra which is 3x that can be added to arr[i-1] as x and arr[i-2] as 2x.
- If arr[0] >=mid and arr[1] >=mid return 1.
- Else return 0.
- In the is_possible_min() function
- If the is_possible_min() function returns true then mid is possible as the minimum value store the max(res, mid) in the res variable, so maximize the minimum value by moving right as f=mid +1
- Else move towards left and try if it is possible by l = mid -1.
- Print the res.
Below is the implementation of the above approach.
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Check if mid is possible as // a minimum element after // any number of operations using // this predicate function bool is_possible_min(vector< int > arr,
int mid)
{ int N = arr.size();
// Traverse from the end
for ( int i = N - 1; i >= 2; i--) {
// mid can't be minimum
if (arr[i] < mid)
return 0;
else {
// Find the 3x
int extra = arr[i] - mid;
// Find the x
extra /= 3;
// Add x to a[i-1]
arr[i - 1] += extra;
// Add 2x to a[i-2]
arr[i - 2] += 2 * extra;
}
}
// Check if the first two elements
// are >= mid because if every element
// is greater than or equal to
// mid we can conclude
// mid as a minimum element
if (arr[0] >= mid && arr[1] >= mid)
return 1;
return 0;
} // Function to find the // maximum possible minimum value void find_maximum_min(vector< int > arr)
{ // Initialize f = 1 and l as the
// maximum element of the array
int f = 1, l = *max_element(arr.begin(),
arr.end());
// Initialize res as INT_MIN
int res = INT_MIN;
// Perform binary search while f<=l
while (f <= l) {
int mid = (f + l) / 2;
// Check if mid is possible
// as a minimum element
if (is_possible_min(arr, mid)) {
// Take the max value of mid
res = max(res, mid);
// Try maximizing the min value
f = mid + 1;
}
// Move left if it is not possible
else {
l = mid - 1;
}
}
// Print the result
cout << res << endl;
} // Driver Code int main()
{ // Initialize the array
vector< int > arr = { 1, 2, 3, 4, 5, 6 };
// Function call
find_maximum_min(arr);
return 0;
} |
// Java program for the above approach import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
// Check if mid is possible as
// a minimum element after
// any number of operations using
// this predicate function
static Boolean is_possible_min( int arr[],
int mid)
{
int N = arr.length;
// Traverse from the end
for ( int i = N - 1 ; i >= 2 ; i--) {
// mid can't be minimum
if (arr[i] < mid)
return false ;
else {
// Find the 3x
int extra = arr[i] - mid;
// Find the x
extra /= 3 ;
// Add x to a[i-1]
arr[i - 1 ] += extra;
// Add 2x to a[i-2]
arr[i - 2 ] += 2 * extra;
}
}
// Check if the first two elements
// are >= mid because if every element
// is greater than or equal to
// mid we can conclude
// mid as a minimum element
if (arr[ 0 ] >= mid && arr[ 1 ] >= mid)
return true ;
return false ;
}
// Function to find the
// maximum possible minimum value
static void find_maximum_min( int arr[])
{
// Initialize f = 1 and l as the
// maximum element of the array
int f = 1 , l = Arrays.stream(arr).max().getAsInt();
// Initialize res as INT_MIN
int res = Integer.MIN_VALUE;
// Perform binary search while f<=l
while (f <= l) {
int mid = l + (f - l) / 2 ;
// Check if mid is possible
// as a minimum element
if (is_possible_min(arr, mid) == true ) {
// Take the max value of mid
res = Math.max(res, mid);
// Try maximizing the min value
f = mid + 1 ;
}
// Move left if it is not possible
else {
l = mid - 1 ;
}
}
// Print the result
System.out.println(res);
}
// Driver Code
public static void main (String[] args)
{
// Initialize the array
int arr[] = { 1 , 2 , 3 , 4 , 5 , 6 };
// Function call
find_maximum_min(arr);
}
} // This code is contributed by hrithikgarg03188. |
# python3 program for the above approach INT_MIN = - 2147483647 - 1
# Check if mid is possible as # a minimum element after # any number of operations using # this predicate function def is_possible_min(arr, mid):
N = len (arr)
# Traverse from the end
for i in range (N - 1 , 1 , - 1 ):
# mid can't be minimum
if (arr[i] < mid):
return 0
else :
# Find the 3x
extra = arr[i] - mid
# Find the x
extra / / = 3
# Add x to a[i-1]
arr[i - 1 ] + = extra
# Add 2x to a[i-2]
arr[i - 2 ] + = 2 * extra
# Check if the first two elements
# are >= mid because if every element
# is greater than or equal to
# mid we can conclude
# mid as a minimum element
if (arr[ 0 ] > = mid and arr[ 1 ] > = mid):
return 1
return 0
# Function to find the # maximum possible minimum value def find_maximum_min(arr):
# Initialize f = 1 and l as the
# maximum element of the array
f, l = 1 , max (arr)
# Initialize res as INT_MIN
res = INT_MIN
# Perform binary search while f<=l
while (f < = l):
mid = (f + l) / / 2
# print(is_possible_min(arr,mid))
# Check if mid is possible
# as a minimum element
if (is_possible_min(arr.copy(), mid)):
# Take the max value of mid
res = max (res, mid)
# Try maximizing the min value
f = mid + 1
# Move left if it is not possible
else :
l = mid - 1
# Print the result
print (res)
# Driver Code if __name__ = = "__main__" :
# Initialize the array
arr = [ 1 , 2 , 3 , 4 , 5 , 6 ]
# Function call
find_maximum_min(arr)
# This code is contributed by rakeshsahni
|
// C# program for the above approach using System;
using System.Linq;
class GFG
{ // Check if mid is possible as
// a minimum element after
// any number of operations using
// this predicate function
static bool is_possible_min( int [] arr, int mid)
{
int N = arr.Length;
// Traverse from the end
for ( int i = N - 1; i >= 2; i--) {
// mid can't be minimum
if (arr[i] < mid)
return false ;
else {
// Find the 3x
int extra = arr[i] - mid;
// Find the x
extra /= 3;
// Add x to a[i-1]
arr[i - 1] += extra;
// Add 2x to a[i-2]
arr[i - 2] += 2 * extra;
}
}
// Check if the first two elements
// are >= mid because if every element
// is greater than or equal to
// mid we can conclude
// mid as a minimum element
if (arr[0] >= mid && arr[1] >= mid)
return true ;
return false ;
}
// Function to find the
// maximum possible minimum value
static void find_maximum_min( int [] arr)
{
// Initialize f = 1 and l as the
// maximum element of the array
int f = 1, l = arr.Max();
// Initialize res as INT_MIN
int res = Int32.MinValue;
// Perform binary search while f<=l
while (f <= l) {
int mid = l + (f - l) / 2;
// Check if mid is possible
// as a minimum element
if (is_possible_min(arr, mid) == true ) {
// Take the max value of mid
res = Math.Max(res, mid);
// Try maximizing the min value
f = mid + 1;
}
// Move left if it is not possible
else {
l = mid - 1;
}
}
// Print the result
Console.WriteLine(res);
}
// Driver Code
public static void Main()
{
// Initialize the array
int [] arr = { 1, 2, 3, 4, 5, 6 };
// Function call
find_maximum_min(arr);
}
} // This code is contributed by Taranpreet |
<script> // Javascript program for the above approach // Check if mid is possible as // a minimum element after // any number of operations using // this predicate function function is_possible_min(arr, mid) {
let N = arr.length;
// Traverse from the end
for (let i = N - 1; i >= 2; i--) {
// mid can't be minimum
if (arr[i] < mid)
return 0;
else {
// Find the 3x
let extra = arr[i] - mid;
// Find the x
extra = Math.floor(extra / 3);
// Add x to a[i-1]
arr[i - 1] += extra;
// Add 2x to a[i-2]
arr[i - 2] += 2 * extra;
}
}
// Check if the first two elements
// are >= mid because if every element
// is greater than or equal to
// mid we can conclude
// mid as a minimum element
if (arr[0] >= mid && arr[1] >= mid)
return 1;
return 0;
} // Function to find the // maximum possible minimum value function find_maximum_min(arr) {
// Initialize f = 1 and l as the
// maximum element of the array
let f = 1, l = max_element(arr);
// Initialize res as INT_MIN
let res = Number.MIN_SAFE_INTEGER
// Perform binary search while f<=l
while (f <= l) {
let mid = Math.ceil((f + l) / 2);
// Check if mid is possible
// as a minimum element
if (is_possible_min(arr, mid)) {
// Take the max value of mid
res = Math.max(res, mid);
// Try maximizing the min value
f = mid + 1;
}
// Move left if it is not possible
else {
l = mid - 1;
}
}
// Print the result
document.write(res);
} function max_element(ar) {
return [...ar].sort((a, b) => - a + b)[0]
} // Driver Code // Initialize the array let arr = [1, 2, 3, 4, 5, 6]; // Function call find_maximum_min(arr); // This code is contributed by saurabh_jaiswal. </script> |
3
Time Complexity: O(N* log(maxval)) where maxval is the maximum element of the array. As we are using a while loop to traverse log(maxval) times as we are decrementing by floor division of 2 every traversal, and is_possible_min function will cost O (N) as we are using a loop to traverse N times.
Auxiliary Space: O(1), as we are not using any extra space.