最近刷leecode总结了一个规律,只要是有序数组,我都会用到二分法,为啥呢? 数据库其实也是二分查找。
左闭有开
$arr = array(1,3,5,8);//
$target = 9;
function searchInsert1($nums, $target)
{
$n = count($nums);
$left = 0;
$right = $n; // 定义target在左闭右开的区间里,[left, right)数组中的数据一定在$nums[0,4) target
//所以条件$left<$right 如果left=right 就会跳出
while ($left < $right)
{ // 因为left == right的时候,在[left, right)是无效的空间
$middle = $left + floor(($right - $left) / 2);
if ($nums[$middle] > $target) {
$right = $middle; // target 在左区间,在[left, middle)中
} else if ($nums[$middle] < $target) {
$left = $middle + 1; // target 在右区间,在 [middle+1, right)中
} else { // nums[middle] == target
return $middle; // 数组中找到目标值的情况,直接返回下标
}
}
return $right;
// 分别处理如下四种情况
// 目标值在数组所有元素之前 [0,0)
// 目标值等于数组中某一个元素 return middle
// 目标值插入数组中的位置 [left, right) ,return right 即可
// 目标值在数组所有元素之后的情况 [left, right),return right 即可
}
左闭右闭 这个我记住了 r i g h t = c o u n t ( right=count( right=count(num)-1; l e f t < = left<= left<=right 如果目标大于中值left = mid +1 如果小于中值 right =mid-1
function searchInsert($nums, $target)
{
$num = count($nums);
$left = 0;
$right = $num-1; //定义taget在左闭右闭区间
//var_dump($left,$right);
while($left <= $right)
{
//var_dump($left,$right);
// 当left==right,区间[left, right]依然有效
$middle = $left + floor(($right - $left) / 2);// 防止溢出 等同于(left + right)/2
//var_dump($middle);
//2
if ($nums[$middle] > $target)
{
$right = $middle - 1; // target 在左区间,所以[left, middle - 1]
} else if ($nums[$middle] < $target) {
$left = $middle + 1; // target 在右区间,所以[middle + 1, right]
//var_dump($left);
} else { // nums[middle] == target
return $middle;
}
}
// 分别处理如下四种情况
// 目标值在数组所有元素之前 [0, -1]
// 目标值等于数组中某一个元素 return middle;
// 目标值插入数组中的位置 [left, right],return right + 1
// 目标值在数组所有元素之后的情况 [left, right], return right + 1
return $right + 1;
};
$a = searchInsert($arr,$target);
var_dump($a);