二分法是一种"分治"思想的算法
二分查找法主要解决在一堆有序的数中找出指定的数类问题,不论这些数是一维数组还是多维数组
二分搜索算法的原理和猜数字游戏类似,猜一个1到100之间的数字,每猜一个数字就和正确的对比是大是小
二分搜索法的步骤
1,选择中间值
2,如果选择的值是待搜索的值,算法结束并返回
3,如果选中的值比待搜索的值小,就返回步骤1并在选中值左边的子数组中继续寻找
4,如果选中的值比待搜索的值大,就返回步骤1并在选中值右边的子数组中继续寻找
最基本的二分查找
在n个元素有序的(升序)整型数组nums中查找目标值target,使用二分法查找目标值,存在就返回下标否则返回-1
示例代码
var bisection = function(nums, target) {
let left = 0, right = nums.length-1; // 设置左边界为数组第0项,右边界为数组的长度-1
while (left <= right) { // 当左边界<=右边界时
let mid = left + ((right - left) >> 1); // 设置中间点,>>1取整数
if (nums[mid] === target) return mid; // 如果中间点等于要查找的值,直接返回
if (nums[mid] > target) { // 如果中间点大于要查找的值,把右边界为中间点-1
right = mid - 1;
} else if (nums[mid] < target) { // 如果中间点小于要查找的值,把左边界为中间点+1
left = mid + 1;
}
}
return -1; // 没找到返回-1
}
二分法变形(查找最后一个等于target的元素)
var bisection = function(nums, target) {
let left = 0,right = nums.length-1;
while(left <= right) { // 当左边界<右边界时
let mid = left + ((right - left) >> 1); // 设置中间点
if (nums[mid] > target) { // 如果中间点>目标,就把右边界改为中间点-1
right = mid - 1;
}else if (nums[mid] <= target){ // 如果中间店>=目标,就把左边界改为中间点+1
left = mid + 1;
}
}
return right; // 返回右边界就是最后一个目标的下标
}
二分法总结
先声明数组的左边界和右边界,当左边界<=右边界时,说明可以对数组继续使用2分进行查找查找
设置中间点,根据查找目标的不同要求,走不同的逻辑
1,查找的目标不分顺序哪个都可以:如果中间点是目标就直接返回,如果中间点>目标就把左边界改为中间点-1
如果中级点<目标,就把左边界+1,直到找到目标,找不到就返回-1
2,查找最后一个等于目标的元素:如果中间点>目标,就把右边界改为中间点-1,如果中间店>=目标
就把左边界改为中间点+1,返回右边界就是最后一个目标的下标