📌  相关文章
📜  通过在给定数组上最多 K 次拆分来最小化可能的最大数组元素

📅  最后修改于: 2021-09-06 05:31:57             🧑  作者: Mango

给定一个由N 个正整数和一个正整数K组成的数组arr[] ,任务是通过将至多 K 个数组元素拆分与它们的值相等的两个数字来最小化数组中存在的最大元素。

例子:

方法:根据以下观察可以解决给定的问题:

  • 如果X可以通过执行至多K 次操作成为数组arr[] 中的最大元素,则存在某个值K (K > X) ,它也可以是数组arr[] 中存在的最大元素 通过对数组元素执行至多K 次分割。
  • 如果通过执行至多K 个操作X不能成为数组A[] 中的最大元素,那么存在一些值K (K < X) ,它也不能通过执行 at 来成为数组arr[] 中的最大元素数组元素的最多K 个分割。
  • 因此,我们的想法是使用二分搜索来查找[1, INT_MAX ]范围内的值,该值可以是最多 K 次拆分后的可能最大值。

 请按照以下步骤解决问题:

  • 初始化两个变量,说lowhigh1数组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