📌  相关文章
📜  可以使 k 次更新相等的最大元素

📅  最后修改于: 2021-10-26 05:31:29             🧑  作者: Mango

给定一个数组和一个值 k。我们必须找到数组可能的相等元素的最大数量,以便我们可以通过增加最多 k 的总数来增加数组的元素。
例子:

朴素的方法:在朴素的方法中,我们有一个O(n^2)时间的算法,我们检查每个元素有多少其他元素可以增加,以便它们变得等于它们。
高效的方法:在这种方法中,首先我们将对数组进行排序。然后我们维护两个数组。第一个是前缀和数组,它存储数组的前缀和,另一个是 maxx[] 数组,它存储到每个点找到的最大元素,即 max[i] 表示从 1 到 i 的最大元素。在将这些值存储在 prefix[] 数组和 maxx[] 数组中后,我们从 1 到 n(数组的元素数)进行二分搜索,以计算可以增加多少个元素以使它们相等。在二分查找中,我们使用一个函数来确定可以增加多少元素以使它们等于单个值

C++
// C++ program to find maximum elements that can
// be made equal with k updates
#include 
using namespace std;
 
// Function to calculate the maximum number of
// equal elements possible with atmost K increment
// of values .Here we have done sliding window
// to determine that whether there are x number of
// elements present which on increment will become
// equal. The loop here will run in fashion like
// 0...x-1, 1...x, 2...x+1, ...., n-x-1...n-1
bool ElementsCalculationFunc(int pre[], int maxx[],
                               int x, int k, int n)
{
    for (int i = 0, j = x; j <= n; j++, i++) {
 
        // It can be explained with the reasoning
        // that if for some x number of elements
        // we can update the values then the
        // increment to the segment (i to j having
        // length -> x) so that all will be equal is
        // (x*maxx[j]) this is the total sum of
        // segment and (pre[j]-pre[i]) is present sum
        // So difference of them should be less than k
        // if yes, then that segment length(x) can be
        // possible return true
        if (x * maxx[j] - (pre[j] - pre[i]) <= k)
            return true;
    }
    return false;
}
 
void MaxNumberOfElements(int a[], int n, int k)
{
    // sort the array in ascending order
    sort(a, a + n);
    int pre[n + 1]; // prefix sum array
    int maxx[n + 1]; // maximum value array
 
    // Initializing the prefix array
    // and maximum array
    for (int i = 0; i <= n; ++i) {
        pre[i] = 0;
        maxx[i] = 0;
    }
 
    for (int i = 1; i <= n; i++) {
 
        // Calculating prefix sum of the array
        pre[i] = pre[i - 1] + a[i - 1];
 
        // Calculating max value upto that position
        // in the array
        maxx[i] = max(maxx[i - 1], a[i - 1]);
    }
 
    // Binary search applied for
    // computation here
    int l = 1, r = n, ans;
    while (l < r) {
        int mid = (l + r) / 2;
 
        if (ElementsCalculationFunc(pre, maxx,
                              mid - 1, k, n)) {
            ans = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }
 
    // printing result
    cout << ans << "\n";
}
 
int main()
{
    int arr[] = { 2, 4, 9 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
    MaxNumberOfElements(arr, n, k);
    return 0;
}


Java
// java program to find maximum elements that can
// be made equal with k updates
 
import java.util.Arrays;
public class GFG {
     
    // Function to calculate the maximum number of
    // equal elements possible with atmost K increment
    // of values .Here we have done sliding window
    // to determine that whether there are x number of
    // elements present which on increment will become
    // equal. The loop here will run in fashion like
    // 0...x-1, 1...x, 2...x+1, ...., n-x-1...n-1
    static boolean ElementsCalculationFunc(int pre[],
                      int maxx[], int x, int k, int n)
    {
        for (int i = 0, j = x; j <= n; j++, i++) {
      
            // It can be explained with the reasoning
            // that if for some x number of elements
            // we can update the values then the
            // increment to the segment (i to j having
            // length -> x) so that all will be equal is
            // (x*maxx[j]) this is the total sum of
            // segment and (pre[j]-pre[i]) is present sum
            // So difference of them should be less than k
            // if yes, then that segment length(x) can be
            // possible return true
            if (x * maxx[j] - (pre[j] - pre[i]) <= k)
                return true;
        }
        return false;
    }
      
    static void MaxNumberOfElements(int a[], int n, int k)
    {
        // sort the array in ascending order
        Arrays.sort(a);
        int []pre = new int[n + 1]; // prefix sum array
        int []maxx = new int[n + 1]; // maximum value array
      
        // Initializing the prefix array
        // and maximum array
        for (int i = 0; i <= n; ++i) {
            pre[i] = 0;
            maxx[i] = 0;
        }
      
        for (int i = 1; i <= n; i++) {
      
            // Calculating prefix sum of the array
            pre[i] = pre[i - 1] + a[i - 1];
      
            // Calculating max value upto that position
            // in the array
            maxx[i] = Math.max(maxx[i - 1], a[i - 1]);
        }
      
        // Binary search applied for
        // computation here
        int l = 1, r = n, ans=0;
        while (l < r) {
              
            int mid = (l + r) / 2;
      
            if (ElementsCalculationFunc(pre, maxx,
                                   mid - 1, k, n))
            {
                ans = mid;
                l = mid + 1;
            }
            else
                r = mid - 1;
        }
      
        // printing result
        System.out.print((int)ans + "\n");
    }
      
    public static void main(String args[]) {
         
        int arr[] = { 2, 4, 9 };
        int n = arr.length;
        int k = 3;
          
        MaxNumberOfElements(arr, n, k);
          
    }
}
 
// This code is contributed by Sam007


Python3
# Python3 program to find maximum elements
# that can be made equal with k updates
 
# Function to calculate the maximum number of
# equal elements possible with atmost K increment
# of values .Here we have done sliding window
# to determine that whether there are x number of
# elements present which on increment will become
# equal. The loop here will run in fashion like
# 0...x-1, 1...x, 2...x+1, ...., n-x-1...n-1
def ElementsCalculationFunc(pre, maxx,
                            x, k, n):
 
    i = 0
    j = x
    while j <= n:
 
        # It can be explained with the reasoning
        # that if for some x number of elements
        # we can update the values then the
        # increment to the segment (i to j having
        # length -> x) so that all will be equal is
        # (x*maxx[j]) this is the total sum of
        # segment and (pre[j]-pre[i]) is present sum
        # So difference of them should be less than k
        # if yes, then that segment length(x) can be
        # possible return true
        if (x * maxx[j] - (pre[j] - pre[i]) <= k):
            return True
 
        i += 1
        j += 1
     
    return False
 
def MaxNumberOfElements( a, n, k):
 
    # sort the array in ascending order
    a.sort()
    pre = [0] * (n + 1) # prefix sum array
    maxx = [0] * (n + 1) # maximum value array
 
    # Initializing the prefix array
    # and maximum array
    for i in range (n + 1):
        pre[i] = 0
        maxx[i] = 0
 
    for i in range(1, n+1):
 
        # Calculating prefix sum of the array
        pre[i] = pre[i - 1] + a[i - 1]
 
        # Calculating max value upto that
        # position in the array
        maxx[i] = max(maxx[i - 1], a[i - 1])
 
    # Binary search applied for
    # computation here
    l = 1
    r = n
    while (l < r) :
        mid = (l + r) // 2
 
        if (ElementsCalculationFunc(pre, maxx,
                                    mid - 1, k, n)):
            ans = mid
            l = mid + 1
         
        else:
            r = mid - 1
 
    # printing result
    print (ans)
 
# Driver Code
if __name__ == "__main__":
 
    arr = [2, 4, 9 ]
    n = len(arr)
    k = 3
    MaxNumberOfElements(arr, n, k)
 
# This code is contributed by Ita_c


C#
// C# program to find maximum elements that can
// be made equal with k updates
using System;
 
class GFG {
     
    // Function to calculate the maximum number of
    // equal elements possible with atmost K increment
    // of values .Here we have done sliding window
    // to determine that whether there are x number of
    // elements present which on increment will become
    // equal. The loop here will run in fashion like
    // 0...x-1, 1...x, 2...x+1, ...., n-x-1...n-1
    static bool ElementsCalculationFunc(int []pre,
                      int []maxx, int x, int k, int n)
    {
        for (int i = 0, j = x; j <= n; j++, i++) {
     
            // It can be explained with the reasoning
            // that if for some x number of elements
            // we can update the values then the
            // increment to the segment (i to j having
            // length -> x) so that all will be equal is
            // (x*maxx[j]) this is the total sum of
            // segment and (pre[j]-pre[i]) is present sum
            // So difference of them should be less than k
            // if yes, then that segment length(x) can be
            // possible return true
            if (x * maxx[j] - (pre[j] - pre[i]) <= k)
                return true;
        }
        return false;
    }
     
    static void MaxNumberOfElements(int []a, int n, int k)
    {
        // sort the array in ascending order
        Array.Sort(a);
        int []pre = new int[n + 1]; // prefix sum array
        int []maxx = new int[n + 1]; // maximum value array
     
        // Initializing the prefix array
        // and maximum array
        for (int i = 0; i <= n; ++i) {
            pre[i] = 0;
            maxx[i] = 0;
        }
     
        for (int i = 1; i <= n; i++) {
     
            // Calculating prefix sum of the array
            pre[i] = pre[i - 1] + a[i - 1];
     
            // Calculating max value upto that position
            // in the array
            maxx[i] = Math.Max(maxx[i - 1], a[i - 1]);
        }
     
        // Binary search applied for
        // computation here
        int l = 1, r = n, ans=0;
        while (l < r) {
             
            int mid = (l + r) / 2;
     
            if (ElementsCalculationFunc(pre, maxx,
                                   mid - 1, k, n))
            {
                ans = mid;
                l = mid + 1;
            }
            else
                r = mid - 1;
        }
     
        // printing result
        Console.Write ((int)ans + "\n");
    }
     
    // Driver code
    public static void Main()
    {
        int []arr = { 2, 4, 9 };
        int n = arr.Length;
        int k = 3;
         
        MaxNumberOfElements(arr, n, k);
    }
}
 
// This code is contributed by Sam007


PHP
 x) so that all will be equal is
        // (x*maxx[j]) this is the total sum of
        // segment and (pre[j]-pre[i]) is present sum
        // So difference of them should be less than k
        // if yes, then that segment length(x) can be
        // possible return true
        if ($x * $maxx[$j] - ($pre[$j] - $pre[$i]) <= $k)
            return true;
    }
    return false;
}
 
function  MaxNumberOfElements($a, $n, $k)
{
    // sort the array in ascending order
    sort($a);
    $pre[$n + 1]=array(); // prefix sum array
    $maxx[$n + 1]=array(); // maximum value array
 
    // Initializing the prefix array
    // and maximum array
    for ($i = 0; $i <= $n; ++$i) {
        $pre[$i] = 0;
        $maxx[$i] = 0;
    }
 
    for ($i = 1; $i <= $n; $i++) {
 
        // Calculating prefix sum of the array
        $pre[$i] = $pre[$i - 1] + $a[$i - 1];
 
        // Calculating max value upto that position
        // in the array
        $maxx[$i] = max($maxx[$i - 1], $a[$i - 1]);
    }
 
    // Binary search applied for
    // computation here
    $l = 1;
    $r = $n;
    $ans;
    while ($l < $r) {
        $mid = ($l + $r) / 2;
 
        if (ElementsCalculationFunc($pre, $maxx,
                            $mid - 1, $k, $n)) {
            $ans = $mid;
            $l = $mid + 1;
        }
        else
            $r = $mid - 1;
    }
 
    // printing result
    echo  $ans , "\n";
}
//Code driven
    $arr = array(2, 4, 9 );
    $n = sizeof($arr) / sizeof($arr[0]);
    $k = 3;
    MaxNumberOfElements($arr, $n, $k);
 
 
#This code is contributed by akt_mit.
?>


Javascript


输出:
2

时间复杂度: O(nlog(n))
空间复杂度: O(n)