Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find elements which need to be removed from an array such that 2*min>max

Consider the following problem:

An array of integers is given. Your goal is to trim the array such that 2*min > max, where min and max are the minimum and maximum elements of the array. You can remove elements either from start or from end of the array if above condition does not meet. The number of removals should be minimized.

For example if the array is

a, b, c, d, e, f

where c is the minimum and e is the maximum, then if 2*c > e is true, we are done. If not, we could remove either from the start (i.e. a,b,c) or from the end (i.e. e, f) such that new min or max would satisfy the condition and removals should be minimum.

I have an O(n2) algorithm for this problem. Can this be solved in time O(n log n)?

like image 706
user2714358 Avatar asked Apr 12 '14 19:04

user2714358


People also ask

How do you remove max and min from an array?

We can remove both the minimum and maximum by removing 2 elements from the front and 3 elements from the back. This results in 2 + 3 = 5 deletions, which is the minimum number possible. Example 2: Input: nums = [0,-4,19,1,8,-2,-3,5] Output: 3 Explanation: The minimum element in the array is nums[1], which is -4.

How do you remove Max from array?

We can remove all instances of the largest number in an array by combining Math. max() and Array. prototype. filter() .

How do you remove an element from an array array?

pop() function: This method is use to remove elements from the end of an array. shift() function: This method is use to remove elements from the start of an array. splice() function: This method is use to remove elements from the specific index of an array.

Can you remove elements from an array?

You can remove elements from the end of an array using pop, from the beginning using shift, or from the middle using splice. The JavaScript Array filter method to create a new array with desired items, a more advanced way to remove unwanted elements.


1 Answers

Note that the problem is to find the largest subarray that fulfills the condition. Realize that if the condition holds for an interval of indices, it holds also for all the intervals included in it. So if we fix one border, we can greedily choose the other border as much away from it as possible.

It's possible to solve this in linear time:

Define ri as the rightmost possible right boundary if you choose element i as the left boundary. We can show that r is monotonous in i, so we can maintain two pointers to i and ri and increment ri as much as possible every time after we increment i by one. Both pointers are incremented a total of O(n) times and we can maintain the range minima / maxima in O(log n) per increment using a heap or binary search tree of the values in the range.

Using a monotonic queue we can maintain the extrema in O(1) and get a total runtime of O(n). Another C++ implementation of the queue can be found here, for example.


Another somewhat less elegant way would be to use a RMQ data structure. It let's you query the min/max in a range in O(1) after O(n log n) preprocessing (O(n) preprocessing is also possible, but complicated and unnecessary here, since the rest of the algorithm is not linear time).

Now fix the left border (there are n possibilities). Use binary search to find the rightmost right boundary which still fulfills the condition (you can check in O(1) whether it does).

This works because the predicate "range fulfills the condition" is monotonous with regard to inclusion (if a range fulfills it, all ranges included in it also fulfill it).

like image 94
Niklas B. Avatar answered Oct 20 '22 19:10

Niklas B.