给定一个由N 个正整数和一个正整数K组成的数组arr[] ,任务是通过将至多 K 个数组元素拆分为与它们的值相等的两个数字来最小化数组中存在的最大元素。
例子:
Input: arr[] = {2, 4, 8, 2}, K = 4
Output: 2
Explanation:
Following sequence of operations are required to be performed:
Operation 1: Splitting arr[1] (= 4) to {2, 2} modifies the array to {2, 2, 2, 8, 2}.
Operation 2: Splitting arr[3] (= 8) to {2, 6} modifies the array to {2, 2, 2, 2, 6, 2}.
Operation 3: Splitting arr[4] (= 6) to {2, 4} modifies the array to {2, 2, 2, 2, 2, 4, 2}.
Operation 4: Splitting arr[5] (= 4) to {2, 2} modifies the array to {2, 2, 2, 2, 2, 2, 2, 2}.
After completing the above operations, the maximum element present in the array is 2.
Input: arr[] = {7, 17}, K = 2
Output: 7
方法:根据以下观察可以解决给定的问题:
- 如果X可以通过执行至多K 次操作成为数组arr[] 中的最大元素,则存在某个值K (K > X) ,它也可以是数组arr[] 中存在的最大元素 通过对数组元素执行至多K 次分割。
- 如果通过执行至多K 个操作X不能成为数组A[] 中的最大元素,那么存在一些值K (K < X) ,它也不能通过执行 at 来成为数组arr[] 中的最大元素数组元素的最多K 个分割。
- 因此,我们的想法是使用二分搜索来查找[1, INT_MAX ]范围内的值,该值可以是最多 K 次拆分后的可能最大值。
请按照以下步骤解决问题:
- 初始化两个变量,说low和high为1和数组arr[]中的最大元素 分别。
- 迭代直到低小于高并执行以下步骤:
- 找到范围[low, high]的中间值,作为mid = (low + high)/2 。
- 初始化一个变量,比如count ,以存储使最大元素等于mid所需的数组元素的最大分割数。
- 遍历给定的数组arr[]并将count的值更新为(arr[i] – 1) / mid以计算所需的拆分次数。
- 如果count的值最多为 K ,则将high的值更新为mid 。
- 否则,将low的值更新为(mid + 1) 。
- 完成上述步骤后,打印high的值作为所得数组中存在的最大元素。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if all array
// elements can be reduced to at
// most mid by at most K splits
int possible(int A[], int N,
int mid, int K)
{
// Stores the number
// of splits required
int count = 0;
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
// Update count
count += (A[i] - 1) / mid;
}
// If possible, return true.
// Otherwise return false
return count <= K;
}
// Function to find the minimum possible
// value of maximum array element that
// can be obtained by at most K splits
int minimumMaximum(int A[], int N, int K)
{
// Set lower and upper limits
int lo = 1;
int hi = *max_element(A, A + N);
int mid;
// Perform Binary Search
while (lo < hi) {
// Calculate mid
mid = (lo + hi) / 2;
// Check if all array elements
// can be reduced to at most
// mid value by at most K splits
if (possible(A, N, mid, K)) {
// Update the value of hi
hi = mid;
}
// Otherwise
else {
// Update the value of lo
lo = mid + 1;
}
}
// Return the minimized maximum
// element in the array
return hi;
}
// Driver Code
int main()
{
int arr[] = { 2, 4, 8, 2 };
int K = 4;
int N = sizeof(arr) / sizeof(arr[0]);
cout << minimumMaximum(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to check if all array
// elements can be reduced to at
// most mid by at most K splits
static boolean possible(int A[], int N,
int mid, int K)
{
// Stores the number
// of splits required
int count = 0;
// Traverse the array arr[]
for(int i = 0; i < N; i++)
{
// Update count
count += (A[i] - 1) / mid;
}
// If possible, return true.
// Otherwise return false
return count <= K;
}
// Function to find the minimum possible
// value of maximum array element that
// can be obtained by at most K splits
static int minimumMaximum(int A[], int N, int K)
{
// Set lower and upper limits
int lo = 1;
Arrays.sort(A);
int hi = A[N - 1];
int mid;
// Perform Binary Search
while (lo < hi)
{
// Calculate mid
mid = (lo + hi) / 2;
// Check if all array elements
// can be reduced to at most
// mid value by at most K splits
if (possible(A, N, mid, K))
{
// Update the value of hi
hi = mid;
}
// Otherwise
else
{
// Update the value of lo
lo = mid + 1;
}
}
// Return the minimized maximum
// element in the array
return hi;
}
// Driver Code
public static void main (String[] args)
{
int arr[] = { 2, 4, 8, 2 };
int K = 4;
int N = arr.length;
System.out.println(minimumMaximum(arr, N, K));
}
}
// This code is contributed by AnkThon
Python3
# Python3 program for the above approach
# Function to check if all array
# elements can be reduced to at
# most mid by at most K splits
def possible(A, N, mid, K):
# Stores the number
# of splits required
count = 0
# Traverse the array arr[]
for i in range(N):
# Update count
count += (A[i] - 1) // mid
# If possible, return true.
# Otherwise return false
return count <= K
# Function to find the minimum possible
# value of maximum array element that
# can be obtained by at most K splits
def minimumMaximum(A, N, K):
# Set lower and upper limits
lo = 1
hi = max(A)
# Perform Binary Search
while (lo < hi):
# Calculate mid
mid = (lo + hi) // 2
# Check if all array elements
# can be reduced to at most
# mid value by at most K splits
if (possible(A, N, mid, K)):
# Update the value of hi
hi = mid
# Otherwise
else:
# Update the value of lo
lo = mid + 1
# Return the minimized maximum
# element in the array
return hi
# Driver Code
if __name__ == '__main__':
arr = [ 2, 4, 8, 2 ]
K = 4
N = len(arr)
print(minimumMaximum(arr, N, K))
# This code is contributed by ipg2016107
C#
// C# program for the above approach
using System;
class GFG{
// Function to check if all array
// elements can be reduced to at
// most mid by at most K splits
static bool possible(int[] A, int N,
int mid, int K)
{
// Stores the number
// of splits required
int count = 0;
// Traverse the array arr[]
for(int i = 0; i < N; i++)
{
// Update count
count += (A[i] - 1) / mid;
}
// If possible, return true.
// Otherwise return false
return count <= K;
}
// Function to find the minimum possible
// value of maximum array element that
// can be obtained by at most K splits
static int minimumMaximum(int[] A, int N, int K)
{
// Set lower and upper limits
int lo = 1;
Array.Sort(A);
int hi = A[N - 1];
int mid;
// Perform Binary Search
while (lo < hi)
{
// Calculate mid
mid = (lo + hi) / 2;
// Check if all array elements
// can be reduced to at most
// mid value by at most K splits
if (possible(A, N, mid, K))
{
// Update the value of hi
hi = mid;
}
// Otherwise
else
{
// Update the value of lo
lo = mid + 1;
}
}
// Return the minimized maximum
// element in the array
return hi;
}
// Driver Code
public static void Main(string[] args)
{
int[] arr = { 2, 4, 8, 2 };
int K = 4;
int N = arr.Length;
Console.WriteLine(minimumMaximum(arr, N, K));
}
}
// This code is contributed by ukasp
Javascript
2
时间复杂度: O(N * log M),其中 M 是数组的最大元素。
辅助空间: O(1)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live