在执行给定操作后最大化 Array 中可能的最小元素
给定一个大小为N的数组arr[] 。任务是在执行给定操作后最大化数组的最小值。在操作中,可以选择值x并且
- 可以从arr[i]元素中减去值3 * x 。
- 将值x添加到arr[i-1] 。和
- 可以将2 * x的值添加到arr[i-2] 。
在任何此类操作之后找到数组的最大可能最小元素。
例子:
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
朴素方法:可以通过从数组末尾执行操作来检查 [1, max(array)] 中最大可能最小值的可能性来解决此问题。
时间复杂度: O(N 2 )
空间复杂度: O(1)
有效方法:这个问题的有效方法是基于 二进制搜索。由于它基于最大化最小值,因此通过在范围[1, max(array)]中应用二进制搜索并通过对数组执行操作来检查 mid 是否可能作为最小元素,使得每个元素都 >=中。请按照以下步骤解决给定的问题:
- 初始化f = 1和l = 数组的最大元素,并将res 初始化为 INT_MIN 。
- 在f<=l时执行二分查找
- 通过在is_possible_min()函数中执行操作来检查 mid 是否可以是最小元素。
- 在is_possible_min()函数中
- 从数组的末尾(N-1)遍历到索引2并检查arr[i]
是否为真返回0 。 - 否则找到额外的3x可以添加到arr[i-1] 作为 x和arr[i-2] 作为 2x 。
- 如果arr[0] >=mid并且arr[1] >=mid返回 1。
- 否则返回0 。
- 从数组的末尾(N-1)遍历到索引2并检查arr[i]
- 在is_possible_min()函数中
- 如果is_possible_min()函数返回 true,则 mid 是可能的,因为最小值将max(res, mid)存储在 res 变量中,因此通过向右移动f=mid +1来最大化最小值
- 否则向左移动并尝试l = mid -1是否可能。
- 打印res 。
下面是上述方法的实现。
C++
// C++ program for the above approach
#include
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 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 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 arr = { 1, 2, 3, 4, 5, 6 };
// Function call
find_maximum_min(arr);
return 0;
}
Java
// 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
# 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#
// 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
Javascript
3
时间复杂度: O(N* log(maxval)) 其中maxval是数组的最大元素。
空间复杂度: O(1)