给定数组arr ,任务是删除最小数量的元素,以便在去除元素后max(arr)<= 2 * min(arr) 。
例子:
Input: arr[] = {4, 5, 3, 8, 3}
Output: 1
Remove 8 from the array.
Input: arr[] = {1, 2, 3, 4}
Output: 1
Remove 1 from the array.
方法:让我们将每个值固定为最小值,例如x,并找到[x,2 * x]范围内的项数。这可以使用前缀和来完成,我们可以使用map(实现自平衡BST)而非数组,因为值可能很大。不在[x,2 * x]范围内的其余项将必须删除。因此,在x的所有值中,我们选择一个在[x,2 * x]范围内最大化项数的值。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the minimum removals from
// arr such that max(arr) <= 2 * min(arr)
int minimumRemovals(int n, int a[])
{
// Count occurrence of each element
map ct;
for (int i = 0; i < n; i++)
ct[a[i]]++;
// Take prefix sum
int sm = 0;
for (auto mn : ct) {
sm += mn.second;
ct[mn.first] = sm;
}
int mx = 0, prev = 0;
for (auto mn : ct) {
// Chosen minimum
int x = mn.first;
int y = 2 * x;
auto itr = ct.upper_bound(y);
itr--;
// Number of elements that are in
// range [x, 2x]
int cr = (itr->second) - prev;
mx = max(mx, cr);
prev = mn.second;
}
// Minimum elements to be removed
return n - mx;
}
// Driver Program to test above function
int main()
{
int arr[] = { 4, 5, 3, 8, 3 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << minimumRemovals(n, arr);
return 0;
}
Python3
# Python3 implementation of the approach
from bisect import bisect_left as upper_bound
# Function to return the minimum removals from
# arr such that max(arr) <= 2 * min(arr)
def minimumRemovals(n, a):
# Count occurrence of each element
ct = dict()
for i in a:
ct[i] = ct.get(i, 0) + 1
# Take prefix sum
sm = 0
for mn in ct:
sm += ct[mn]
ct[mn] = sm
mx = 0
prev = 0;
for mn in ct:
# Chosen minimum
x = mn
y = 2 * x
itr = upper_bound(list(ct), y)
# Number of elements that are in
# range [x, 2x]
cr = ct[itr] - prev
mx = max(mx, cr)
prev = ct[mn]
# Minimum elements to be removed
return n - mx
# Driver Code
arr = [4, 5, 3, 8, 3]
n = len(arr)
print(minimumRemovals(n, arr))
# This code is contributed by Mohit Kumar
输出:
1