二分法 两种写法你会的是哪个?

最近刷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);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mr.杰瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值