「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战」
二分法基本模版
function binarySearch(nums, target) {
let left = 0, right = ...;
while(...) {
const mid = left + Math.floor((right - left) / 2);
if(num[mid] == target) {
...
} else if(nums[mid] < target) {
left = ...
} else if(nums[mid] > target) {
right = ...
}
}
}
二分法哪里不简单
细节是魔鬼
- while里到底是要用<=还是<;
- mid到底是加一还是减一;
题目:35. 搜索插入位置
解答
function searchInsert(nums, target) {
let left = 0;
let right = nums.length - 1;
while (left <= right) {
let mid = left + Math.floor((right - left) / 2);
if (nums[mid] == target) {
return mid;
} else if(nums[mid] < target){
left = mid + 1;
} else if(nums[mid] > target){
right = mid - 1;
}
}
return left;
};
分析:
这是一个基本的二分搜索
- 为什么while循环的条件是<=,而不是<?
答:因为初始化right的赋值是nums.length-1,即最后一个元素的索引,而不是nums.length;相当于两端都闭区间[left, right],这个区间其实就是每次进行搜索的区间。 - 为什么是left = mid + 1和reight = mid - 1
答:因为我们是搜索区间[left, right],当mid不是要找的target值时,下一步应该去[left, mid - 1]或[mid+1,right]里面去找。 - 该算法有什么缺陷?
答:当查找数组为[1,3,3,3,4],target为3时,该算法返回的是索引2。但如果我想得到target的左边界,即索引1,或者想得到右边界,即索引3,该算法是无法处理的。