Searching for a range of target values in an array
Searching for a range of target values in a sorted array using binary search template 3. Original algorithm from leetcode:
https://leetcode.com/explore/learn/card/binary-search/135/template-iii/936/
In my opinion, this algorithm is the best for finding "peaks". I modified it to better fit the task at hand.
by Yurii Predborskyi
June 21, 2018
JavaScript
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
const searchRange = function(nums, target) {
// find edge function for finding start and finish
function findEdge(left, right, direction) {
function isEdge(i) {
const len = i + direction;
if (len >= 0 && len < nums.length) {
return nums[i + direction] !== target;
}
return true;
}
function finalCheck(index) {
if (nums[index] === target && isEdge(index)) {
return index;
}
if (nums[index - direction] === target && isEdge(index - direction)) {
return index - direction;
}
return -1;
}
while (left + 1 < right) {
const mid = Math.floor((left + right) / 2);
if (nums[mid] === target) {
if (isEdge(mid)) {
return mid;
} else if (direction > 0) {
left = mid;
} else {
right = mid;
}
}
if (nums[mid] > target) {
right = mid;
}
if (nums[mid] < target) {
left = mid;
}
}
return finalCheck(direction > 0 ? right : left);
}
// end of findEdge
let start = -1;
let finish = -1;
if (nums.length < 3) {
// nums smaller than required minimum length to find range
// use brute force
for (let i = 0; i < nums.length; i++) {
if (nums[i] === target) {
if (start === -1) {
start = i;
}
finish = i;
}
}
} else {
// main function
let left = 0;
let right = nums.length - 1;
let mid = 0;
// find mid using binary search
while (left + 1 < right) {
mid = Math.floor((left + right) / 2);
if (nums[mid] === target) {
break;
}
if (nums[mid] > target) {
right = mid;
}
if (nums[mid] < target) {
left = mid;
}
}
start = findEdge(left, mid, -1);
finish = findEdge(mid, right, 1);
}
return [start, finish];
};
let tests = [{
...