Usually, we would have to traverse through every element O(n) to find a target in a group. However, when our elements are sorted, we can cut the aspects we’re looking at in half. Fewer elements = faster search time. Binary search has a search time of O(log n).
let search = (nums, target) => {let low = 0, high = nums.length-1;while (low < high){let mid = low + Math.floor((high - low + 1)/2);if (target < nums[mid]){high = mid - 1} else {low = mid;}}return nums[low] == target ? low : -1;};search([-1,0,3,5,9,12], 9)//result: 4
First, we define two variables that store the indexes of our upper and lower limits. Initially, we set the boundary to the entire array.
let low = 0, high = nums.length-1;
The ‘mid’ variable points to the central element within our boundary. This essentially splits our limit into two parts. This is where binary search saves time by cutting the elements searched in half.
let mid = low + Math.floor((high - low + 1)/2);
We run a conditional to check if our target is less than our mid; if so, we adjust our upper limit to our mid index. If our target is greater than mid, we adjust our lower limit to our mid index.
if (target < nums[mid]){high = mid - 1} else {low = mid;}
We use a ‘While’ loop to keep shrinking the boundary, narrowing our search pool. The loop exits when high = low, indicating only one element remains.
while (low < high){
Finally, the mid variable has narrowed down to our target. We’ll perform a check
to confirm we’ve found our target. Using a ternary operator and returning -1
if it is not our target.
return nums[low] == target ? low : -1;
let mid = Math.floor((low + high) / 2) // Overflow very likelylet mid = low + Math.floor((high + low) / 2) // less likely, still possible
let mid = low + Math.floor((high - low) / 2) // left/lowerlet mid = low + Math.floor((high - low + 1) / 2) // right/upper
high = mid + 1
high = mid
While(low < high)
because the loop only exits on the condition of low = high. Pointing to the same element, which always exists.let mid = low + ((high - low) / 2) // Bad! We should use right/upper midif (target < nums[mid]){high = mid - 1} else {low = mid}
let mid = low + ((high - low + 1) / 2); // Bad! We should use left/lower midif (target > nums[mid]) {low = mid + 1; // mid excluded} else {high = mid; // mid included}
Legal Stuff