📜  在阵列上进行K加法运算后,最大化中位数

📅  最后修改于: 2021-05-14 00:25:09             🧑  作者: Mango

给定一个由N个元素组成的数组arr []和一个整数K,任务是在数组上最多执行K个操作。在一次操作中,将任意元素增加数组之一。进行K次这样的运算后,找到最大中位数。

例子:

方法:

  1. 按升序对数组进行排序。
  2. 由于中位数是数组左半部分执行操作的中间元素,因此它将毫无价值,因为它不会增加中位数。
  3. 在下半部分执行操作,然后开始执行从第n / 2个元素到最后一个元素的操作。
  4. 如果N等于偶数,则从n / 2个元素开始到最后进行操作。
  5. 使用二进制搜索,我们将在执行K运算后检查是否有可能作为中位数的任何数字。
  6. 如果中位数是可能的,那么我们将检查下一个大于当前计算的中位数的数字。否则,中位数的最后可能值是所需结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to check operation can be
// perform or not
bool possible(int arr[], int N,
              int mid, int K)
{
 
    int add = 0;
 
    for (int i = N / 2 - (N + 1) % 2;
         i < N; ++i) {
 
        if (mid - arr[i] > 0) {
 
            // Number of operation to
            // perform s.t. mid is median
            add += (mid - arr[i]);
 
            if (add > K)
                return false;
        }
    }
 
    // If mid is median of the array
    if (add <= K)
        return true;
    else
        return false;
}
 
// Function to find max median
// of the array
int findMaxMedian(int arr[], int N,
                  int K)
{
 
    // Lowest possible median
    int low = 1;
    int mx = 0;
 
    for (int i = 0; i < N; ++i) {
        mx = max(mx, arr[i]);
    }
 
    // Highest possible median
    long long int high = K + mx;
 
    while (low <= high) {
 
        int mid = (high + low) / 2;
 
        // Checking for mid is possible
        // for the median of array after
        // doing at most k operation
        if (possible(arr, N, mid, K)) {
            low = mid + 1;
        }
 
        else {
            high = mid - 1;
        }
    }
 
    if (N % 2 == 0) {
 
        if (low - 1 < arr[N / 2]) {
            return (arr[N / 2] + low - 1) / 2;
        }
    }
 
    // Return the max possible ans
    return low - 1;
}
 
// Driver Code
int main()
{
    // Given array
    int arr[] = { 1, 3, 6 };
 
    // Given number of operation
    int K = 10;
 
    // Size of array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Sort the array
    sort(arr, arr + N);
 
    // Function call
    cout << findMaxMedian(arr, N, K);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to check operation can be
// perform or not
static boolean possible(int arr[], int N,
                        int mid, int K)
{
    int add = 0;
 
    for(int i = N / 2 - (N + 1) % 2;
            i < N; ++i)
    {
        if (mid - arr[i] > 0)
        {
 
            // Number of operation to
            // perform s.t. mid is median
            add += (mid - arr[i]);
 
            if (add > K)
                return false;
        }
    }
 
    // If mid is median of the array
    if (add <= K)
        return true;
    else
        return false;
}
 
// Function to find max median
// of the array
static int findMaxMedian(int arr[], int N,
                                    int K)
{
 
    // Lowest possible median
    int low = 1;
    int mx = 0;
 
    for(int i = 0; i < N; ++i)
    {
        mx = Math.max(mx, arr[i]);
    }
 
    // Highest possible median
    int high = K + mx;
 
    while (low <= high)
    {
        int mid = (high + low) / 2;
 
        // Checking for mid is possible
        // for the median of array after
        // doing at most k operation
        if (possible(arr, N, mid, K))
        {
            low = mid + 1;
        }
 
        else
        {
            high = mid - 1;
        }
    }
     
    if (N % 2 == 0)
    {
        if (low - 1 < arr[N / 2])
        {
            return (arr[N / 2] + low - 1) / 2;
        }
    }
     
    // Return the max possible ans
    return low - 1;
}
 
// Driver code
public static void main(String[] args)
{
     
    // Given array
    int arr[] = { 1, 3, 6 };
     
    // Given number of operation
    int K = 10;
     
    // Size of array
    int N = arr.length;
     
    // Sort the array
    Arrays.sort(arr);
     
    // Function call
    System.out.println(findMaxMedian(arr, N, K));
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
 
# Function to check operation can be
# perform or not
def possible(arr, N, mid, K):
 
    add = 0
 
    for i in range(N // 2 - (N + 1) % 2, N):
 
        if (mid - arr[i] > 0):
 
            # Number of operation to
            # perform s.t. mid is median
            add += (mid - arr[i])
 
            if (add > K):
                return False
 
    # If mid is median of the array
    if (add <= K):
        return True
    else:
        return False
 
# Function to find max median
# of the array
def findMaxMedian(arr, N,K):
 
    # Lowest possible median
    low = 1
    mx = 0
 
    for i in range(N):
        mx = max(mx, arr[i])
 
    # Highest possible median
    high = K + mx
 
    while (low <= high):
 
        mid = (high + low) // 2
 
        # Checking for mid is possible
        # for the median of array after
        # doing at most k operation
        if (possible(arr, N, mid, K)):
            low = mid + 1
        else :
            high = mid - 1
 
    if (N % 2 == 0):
 
        if (low - 1 < arr[N // 2]):
            return (arr[N // 2] + low - 1) // 2
 
    # Return the max possible ans
    return low - 1
 
# Driver Code
if __name__ == '__main__':
     
    # Given array
    arr = [1, 3, 6]
 
    # Given number of operation
    K = 10
 
    # Size of array
    N = len(arr)
 
    # Sort the array
    arr = sorted(arr)
 
    # Function call
    print(findMaxMedian(arr, N, K))
 
# This code is contributed by Mohit Kumar


C#
// C# program for the above approach
using System;
class GFG{
  
// Function to check operation can be
// perform or not
static bool possible(int []arr, int N,
                       int mid, int K)
{
    int add = 0;
  
    for(int i = N / 2 - (N + 1) % 2;
            i < N; ++i)
    {
        if (mid - arr[i] > 0)
        {
  
            // Number of operation to
            // perform s.t. mid is median
            add += (mid - arr[i]);
  
            if (add > K)
                return false;
        }
    }
  
    // If mid is median of the array
    if (add <= K)
        return true;
    else
        return false;
}
  
// Function to find max median
// of the array
static int findMaxMedian(int []arr, int N,
                                    int K)
{
  
    // Lowest possible median
    int low = 1;
    int mx = 0;
  
    for(int i = 0; i < N; ++i)
    {
        mx = Math.Max(mx, arr[i]);
    }
  
    // Highest possible median
    int high = K + mx;
  
    while (low <= high)
    {
        int mid = (high + low) / 2;
  
        // Checking for mid is possible
        // for the median of array after
        // doing at most k operation
        if (possible(arr, N, mid, K))
        {
            low = mid + 1;
        }
  
        else
        {
            high = mid - 1;
        }
    }
      
    if (N % 2 == 0)
    {
        if (low - 1 < arr[N / 2])
        {
            return (arr[N / 2] + low - 1) / 2;
        }
    }
      
    // Return the max possible ans
    return low - 1;
}
  
// Driver code
public static void Main(string[] args)
{
      
    // Given array
    int []arr = { 1, 3, 6 };
      
    // Given number of operation
    int K = 10;
      
    // Size of array
    int N = arr.Length;
      
    // Sort the array
    Array.Sort(arr);
      
    // Function call
    Console.Write(findMaxMedian(arr, N, K));
}
}
  
// This code is contributed by rock_cool


Javascript


输出:
9

时间复杂度: O(N * log(K + M)) ,其中M是给定数组的最大元素。
辅助空间: O(1)