Skip to content
Related Articles

Related Articles

Remove minimum elements from array so that max <= 2 * min
  • Difficulty Level : Medium
  • Last Updated : 27 Dec, 2019

Given an array arr, the task is to remove minimum number of elements such that after their removal, max(arr) <= 2 * min(arr).

Examples:

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.

Approach: Let us fix each value as the minimum value say x and find number of terms that are in range [x, 2*x]. This can be done using prefix-sums, we can use map (implements self balancing BST) instead of array as the values can be large. The remaining terms which are not in range [x, 2*x] will have to be removed. So, across all values of x, we choose the one which maximises the number of terms in range [x, 2*x].

Below is the implementation of the above approach:

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
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<int, int> 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
Output:
1



My Personal Notes arrow_drop_up
Recommended Articles
Page :