Minimize the maximum value in array by incrementing and decrementing.
Last Updated :
09 Mar, 2024
Given array arr[] of size N, the task is to minimize the maximum value in given array by increasing arr[i] by 1 and decreasing arr[i + 1] by 1 any number of times.
Examples:
Input: arr[] = {3, 7, 1, 6}
Output: 5
Explanation: Initially we have arr[] = {3, 7, 1, 6}
- Choose i = 1 (considering 1 index), arr[] becomes {4, 6, 1, 6}
- Choose i = 1, arr[] becomes {5, 5, 1, 6}
- Choose i = 3, arr[] becomes {5, 5, 2, 5}
5 is the minimum number we can get by performing above operations any number of times
Input: arr[] = {10, 1}
Output: 10
Explanation: 10 is the minimum number we can get by performing above operations any number of times.
Approach: Implement the idea below to solve the problem
Binary Search can be used to solve this problem. Idea is for every number we can check whether it is possible to make it as maximum element of array or not by performing given operations. We will binary search on this monotonic function it will be of type FFFFFTTTTT initially function will be false for smaller values and as the values increase it will keep returning true. We have to find first time when function becomes true.
Step-by-step approach:
- Declare function test() to check if it is possible to make maximum value of array at most mid
- Declare variable prev which is initially set to zero (which is extra number that we need to carry backwards so to make i’th element at most mid)
- Iterate i from N – 1 to 1 and follow given steps for each i:
- if sum of A[i] and prev is greater than mid update prev as A[i] + prev – mid
- else make prev as 0
- finally return whether sum of first element and prev is less than equal to mid or not
- Declare low = 0 and high as sum of array A[]
- Run while loop till high and low are not adjacent
- Declare variable mid set as (low + high) / 2
- if test function is true for mid update high as mid otherwise low as mid + 1
- if test() function is true for low return low otherwise return high
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
#define int long long
int minimizeMaximumVal( int A[], int N)
{
auto test = [&]( int mid) -> bool {
int prev = 0;
for ( int i = N - 1; i >= 1; i--) {
if (A[i] + prev > mid) {
prev = A[i] + prev - mid;
}
else
prev = 0;
}
return A[0] + prev <= mid;
};
int low = 0, high = accumulate(A, A + N, 0LL);
while (high - low > 1) {
int mid = (low + high) / 2;
if (test(mid)) {
high = mid;
}
else {
low = mid + 1;
}
}
if (test(low))
return low;
else
return high;
}
int32_t main()
{
int N = 4;
int A[] = { 3, 7, 1, 6 };
cout << minimizeMaximumVal(A, N) << endl;
return 0;
}
|
Java
class Main {
static boolean test( int mid, int [] A, int N)
{
int prev = 0 ;
for ( int i = N - 1 ; i > 0 ; i--) {
if (A[i] + prev > mid) {
prev = A[i] + prev - mid;
}
else {
prev = 0 ;
}
}
return A[ 0 ] + prev <= mid;
}
static int minimizeMaximumValue( int [] A, int N)
{
int low = 0 , high = 0 ;
for ( int value : A) {
high += value;
}
while (high - low > 1 ) {
int mid = (low + high) / 2 ;
if (test(mid, A, N)) {
high = mid;
}
else {
low = mid + 1 ;
}
}
if (test(low, A, N)) {
return low;
}
else {
return high;
}
}
public static void main(String[] args)
{
int N = 4 ;
int [] A = { 3 , 7 , 1 , 6 };
System.out.println(minimizeMaximumValue(A, N));
}
}
|
C#
using System;
class Program
{
const int Mod = 1000000007;
static bool Test( long mid, long [] A, int N)
{
long prev = 0;
for ( int i = N - 1; i >= 1; i--)
{
if (A[i] + prev > mid)
{
prev = A[i] + prev - mid;
}
else
{
prev = 0;
}
}
return A[0] + prev <= mid;
}
static long MinimizeMaximumVal( long [] A, int N)
{
long low = 0, high = 0;
for ( int i = 0; i < N; i++)
{
high += A[i];
}
while (high - low > 1)
{
long mid = (low + high) / 2;
if (Test(mid, A, N))
{
high = mid;
}
else
{
low = mid + 1;
}
}
if (Test(low, A, N))
return low;
else
return high;
}
static void Main()
{
int N = 4;
long [] A = { 3, 7, 1, 6 };
Console.WriteLine(MinimizeMaximumVal(A, N));
}
}
|
Javascript
function minimize_maximum_val(A, N) {
function test(mid) {
let prev = 0;
for (let i = N - 1; i > 0; i--) {
if (A[i] + prev > mid) {
prev = A[i] + prev - mid;
} else {
prev = 0;
}
}
return A[0] + prev <= mid;
}
let low = 0;
let high = A.reduce((a, b) => a + b, 0);
while (high - low > 1) {
let mid = Math.floor((low + high) / 2);
if (test(mid)) {
high = mid;
} else {
low = mid + 1;
}
}
if (test(low)) {
return low;
} else {
return high;
}
}
const N = 4;
const A = [3, 7, 1, 6];
console.log(minimize_maximum_val(A, N));
|
Python3
def minimize_maximum_val(A, N):
def test(mid):
prev = 0
for i in range (N - 1 , 0 , - 1 ):
if A[i] + prev > mid:
prev = A[i] + prev - mid
else :
prev = 0
return A[ 0 ] + prev < = mid
low, high = 0 , sum (A)
while high - low > 1 :
mid = (low + high) / / 2
if test(mid):
high = mid
else :
low = mid + 1
if test(low):
return low
else :
return high
if __name__ = = "__main__" :
N = 4
A = [ 3 , 7 , 1 , 6 ]
print (minimize_maximum_val(A, N))
|
Time Complexity: O(N log (N))
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...