Lower and Upper Bound Binary Search
Find the first and last insertion points for a value in a sorted array with a custom comparator, then count duplicates in logarithmic time.
Code
export function lowerBound(array, target, compare = defaultCompare) {
assertArray(array);
let low = 0;
let high = array.length;
while (low < high) {
const mid = (low + high) >>> 1;
if (compare(array[mid], target) < 0) low = mid + 1;
else high = mid;
}
return low;
}
export function upperBound(array, target, compare = defaultCompare) {
assertArray(array);
let low = 0;
let high = array.length;
while (low < high) {
const mid = (low + high) >>> 1;
if (compare(array[mid], target) <= 0) low = mid + 1;
else high = mid;
}
return high;
}
export function countOccurrences(array, target, compare) {
return upperBound(array, target, compare) - lowerBound(array, target, compare);
}
function defaultCompare(left, right) {
return left < right ? -1 : left > right ? 1 : 0;
}
function assertArray(array) {
if (!Array.isArray(array)) throw new TypeError("array must be an array");
}
const scores = [10, 20, 20, 20, 35, 50];
console.log(lowerBound(scores, 20));
console.log(upperBound(scores, 20));
console.log(countOccurrences(scores, 20));
console.log(lowerBound(scores, 25));Report a problem with this exampleOpens a pre-filled issue on GitHub.