 GeeksforGeeks App
Open App Browser
Continue

# Remove minimum elements from array so that max <= 2 * min

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.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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 ``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);``    ``cout << minimumRemovals(n, arr);``    ``return` `0;``}`

## Java

 `// Java implementation of the approach``import` `java.util.*;` `public` `class` `Main {``    ``// Function to return the minimum removals from``    ``// arr such that max(arr) <= 2 * min(arr)``    ``public` `static` `int` `minimumRemovals(``int` `n, ``int``[] a) {``        ``// Count occurrence of each element``        ``Map ct = ``new` `HashMap<>();``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``ct.put(a[i], ct.getOrDefault(a[i], ``0``) + ``1``);``        ``}``    ` `        ``// Take prefix sum``        ``int` `sm = ``0``;``        ``for` `(``int` `mn : ct.keySet()) {``            ``sm += ct.get(mn);``            ``ct.put(mn, sm);``        ``}``    ` `        ``int` `mx = ``0``, prev = ``0``;``        ``for` `(``int` `mn : ct.keySet()) {``            ``// Chosen minimum``            ``int` `x = mn;``            ``int` `y = ``2` `* x;``            ``List keysList = ``new` `ArrayList<>(ct.keySet());``            ``int` `index = Collections.binarySearch(keysList, y);``            ``int` `pos = index >= ``0` `? index : -(index + ``1``) - ``1``;``            ``Integer itr = pos >= ``0` `? ct.get(keysList.get(pos)) : ``null``;``    ` `            ``// Number of elements that are in``            ``// range [x, 2x]``            ``int` `cr = (itr != ``null` `? itr : ``0``) - prev;``            ``mx = Math.max(mx, cr);``            ``prev = ct.get(mn);``        ``}``    ` `        ``// Minimum elements to be removed``        ``return` `n - mx;``    ``}` `    ``// Driver Program to test above function``    ``public` `static` `void` `main(String[] args) {``        ``int``[] arr = { ``4``, ``5``, ``3``, ``8``, ``3` `};``        ``int` `n = arr.length;``        ``System.out.println(minimumRemovals(n, arr));``    ``}``}` `// This code is contributed by codebraxnzt`

## 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`

## C#

 `// C# program for the above approach` `using` `System;``using` `System.Collections.Generic;` `public` `class` `MainClass``{``    ``// Function to return the minimum removals from``    ``// arr such that max(arr) <= 2 * min(arr)``    ``public` `static` `int` `minimumRemovals(``int` `n, ``int``[] a)``    ``{``        ``// Count occurrence of each element``        ``Dictionary<``int``, ``int``> ct = ``new` `Dictionary<``int``, ``int``>();``        ``for` `(``int` `i = 0; i < n; i++)``        ``{``            ``if` `(ct.ContainsKey(a[i]))``            ``{``                ``ct[a[i]]++;``            ``}``            ``else``            ``{``                ``ct[a[i]] = 1;``            ``}``        ``}` `        ``// Take prefix sum``        ``int` `sm = 0;``        ``List<``int``> keysList = ``new` `List<``int``>(ct.Keys);``        ``keysList.Sort();``        ``foreach` `(``int` `mn ``in` `keysList)``        ``{``            ``sm += ct[mn];``            ``ct[mn] = sm;``        ``}` `        ``int` `mx = 0, prev = 0;``        ``foreach` `(``int` `mn ``in` `keysList)``        ``{``            ``// Chosen minimum``            ``int` `x = mn;``            ``int` `y = 2 * x;` `            ``int` `index = keysList.BinarySearch(y);``            ``int` `pos = index >= 0 ? index : -(index + 1) - 1;``            ``int` `itr = pos >= 0 ? ct[keysList[pos]] : 0;` `            ``// Number of elements that are in``            ``// range [x, 2x]``            ``int` `cr = itr - prev;``            ``mx = Math.Max(mx, cr);``            ``prev = ct[mn];``        ``}` `        ``// Minimum elements to be removed``        ``return` `n - mx;``    ``}` `    ``// Driver Program to test above function``    ``public` `static` `void` `Main()``    ``{``        ``int``[] arr = { 4, 5, 3, 8, 3 };``        ``int` `n = arr.Length;``        ``Console.WriteLine(minimumRemovals(n, arr));``    ``}``}` `// This code is contributed by Prince Kumar`

## Javascript

 `// JavaScript implementation of the approach``// Function to return the minimum removals from arr such that max(arr) <= 2 * min(arr)` `function` `minimumRemovals(n, a){``    ``// Import upper_bound from bisect``    ``const upper_bound = (arr, x) => {``        ``let low = 0, high = arr.length;``        ``while` `(low < high) {``            ``const mid = (low + high) >>> 1;``            ``if` `(x >= arr[mid]) {``                ``low = mid + 1;``            ``} ``else` `{``                ``high = mid;``            ``}``        ``}``        ``return` `low;``    ``}``  ` `    ``// Count occurrence of each element``    ``let ct = ``new` `Map();``    ``for` `(let i of a){``        ``ct.set(i, (ct.get(i) || 0) + 1);``    ``}` `    ``// Take prefix sum``    ``let sm = 0;``    ``for` `(let mn of ct.keys()){``        ``sm += ct.get(mn);``        ``ct.set(mn, sm);``    ``}` `    ``let mx = 0;``    ``let prev = 0;``    ``for` `(let mn of ct.keys()){``        ``// Chosen minimum``        ``let x = mn;``        ``let y = 2 * x;``        ``let itr = upper_bound(Array.from(ct.keys()), y);` `        ``// Number of elements that are in range [x, 2x]``        ``let cr = ct.get([...ct.keys()][itr-1]) - ct.get(mn) + prev;``        ``mx = Math.max(mx, cr);``        ``prev = ct.get(mn) - (ct.get(mn - 1) || 0);``    ``}` `    ``// Minimum elements to be removed``    ``return` `n - mx;``}` `// Driver Code``let arr = [4, 5, 3, 8, 3];``let n = arr.length;``console.log(minimumRemovals(n, arr));` `// This code is contributed by princekumaras`

Output

`1`

My Personal Notes arrow_drop_up