# Most efficient way to find range in array

I have a sorted array of integer numbers that can be positive of negative:

[ -30, -13, -10, -4, -1, 4, 23, 55, 90, 234, 433, 500 ]

I need to find the indexes of the lowest number that is greater or equal to zero and the greatest number that is lower or equal to 400. What is the most efficient way to do it? (I am using JavaScript but any language or pseudo code will be fine)

## Answers

O(log N)

JSFiddle: http://jsfiddle.net/vCY68/

function binaryIndexOf(data, criteria) { 'use strict'; var minIndex = 0; var maxIndex = data.length - 1; var currentIndex; var currentElement; var result = null; while (minIndex <= maxIndex) { currentIndex = (minIndex + maxIndex) / 2 | 0; currentElement = data[currentIndex]; var comparison = criteria(currentElement); if (comparison[0] == 'right') { minIndex = currentIndex + 1; } else { maxIndex = currentIndex - 1; } if (comparison[1]) { result = currentIndex; } } return result; } var firstPositive = binaryIndexOf(data, function(value) { return value < 0 ? ['right', false] : ['left', true]; }); var lastLess400 = binaryIndexOf(data, function(value) { return value > 400 ? ['left', false] : ['right', true]; });

Comparison function here returns 2 values: 1st is where to move after this comparison. 2nd is if the current value is acceptable.

PS: to save a time on implementing binary search the code from http://oli.me.uk/2013/06/08/searching-javascript-arrays-with-a-binary-search/ was taken, with minor modifications

PPS: potentially you can reduce number of comparisons if you initialize the search range manually and parameterize the second search with firstPositive + 1 start index

Do a binary search for 0 and for 400 in your array. If you hit 0 or 400 then that is the answer, otherwise check the array element that you reach as well as the elements to the left or right to see which one is the greatest smaller than 0 or largest less than 400. Complexity is O(log n) if your array is size n.

Do a binary search for the lowest element greater than 0 and for he highest element greater than 400 in your array.

You would need to do a slight modification in your search to check everytime if the element next to your index is still decreasing or increasing. For ex : if you reach the value 3 and the previous elemnt is -2, then 3 would be your answer(i.e instead of comparing for equality you are searching for the next highest or lowest value)

You will need 2 O(logn) operations to achieve this.