给定一个数组和一个值 k。我们必须找到数组可能的相等元素的最大数量,以便我们可以通过增加最多 k 的总数来增加数组的元素。
例子:
Input : array = { 2, 4, 9 }, k = 3
Output : 2
We are allowed to do at most three increments. We can make two elements 4 by increasing 2 by 2. Note that we can not make two elements 9 as converting 4 to 9 requires 5 increments.
Input : array = { 5, 5, 3, 1 }, k = 5
Output : 3
Explanation: Here 1st and 2nd elements are equal. Then we can increase 3rd element 3 upto 5. Then k becomes (k-2) = 3. Now we can’t increase 1 to 5 because k value is 3 and we need 4 for the updation. Thus equal elements possible are 3. Here we can also increase 1 to 5. Then also we have 3 because we can’t update 3 to 5.
Input : array = { 5, 5, 3, 1 }, k = 6
Output : 4
朴素的方法:在朴素的方法中,我们有一个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)