704. Binary Search
The problem:
Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1. You must write an algorithm with O(log n) runtime complexity.
For this one I came up with three solutions:
The “Illegal”
var search = function (nums, target) {
return nums.indexOf(target) // I ain't writting no more code.
};
Results:
Runtime: 0ms
Memory: 58.4mb
Beats: 100%
This is technically right, but I don’t think any recruiter will let this fly.
The Brute-force-ish
function search(nums, target) {
let left = 0;
let right = nums.length -1;
while(left <= right) {
if(nums[left] === target) {
return left;
}
if(nums[right] === target) {
return right;
}
if(nums[left] < target) {
left++
}
if(nums[right] > target) {
right--
}
}
return -1;
};
While this is not a brute force approach on its enterity, we are still not doing real binary search, let’s see it line by line:
function search(nums, target) {
let left = 0; // Pointer to the left
let right = nums.length -1; // Pointer to the left
while(left <= right) {
if(nums[left] === target) { // If we found the number with the left, then we return
return left;
}
if(nums[right] === target) { // If we found the number with the right, then we return
return right;
}
if(nums[left] < target) { // If left is less than target, then we move the pointer 1 index to the right
left++
}
if(nums[right] > target) { //If right is more than target, then we move the pointer 1 index to the left
right--
}
}
return -1;
};
In the best case scenario, we find the target in the first few indexes, but if the target is right in the middle, then we are losing a lot of time.
While this is not objectivelly a bad solution to the problem we could implement something even easier and better performant.
Results:
Runtime: 0ms
Memory: 59.1mb
Beats: 100%
The “Optimal”
var search = function (nums, target) {
let left = 0; // Pointer to the left
let right = nums.length - 1; //Pointer to the right
while (left <= right) { // While left is less that right, we keep going
const mid = Math.floor((left + right) / 2); // We get the center of the two pointers
if (nums[mid] === target) { // If mid is the target, that's our answer
return mid;
} else if (nums[mid] < target) { // if nums[mid] is less than target, then we add 1 to mid
left = mid + 1;
} else {
right = mid - 1; // The opossite
}
}
return -1; // We didn't found shit.
};
Results:
Runtime: 0ms
Memory: 58.1mb
Beats: 100%