你真的会二分么

这次我敢打包票我是真的 完全 进了一大步了解了二分。

这个内容对在座的各位大佬来说肯定还是很简单的,菜鸡现在才搞懂,个人还是觉得是有里程碑的意义的。

1.元素完全确定的二分查找

这是二分查找的最简单形式,就是你要查找的值确定,且不重复。
这种形式下,只要找到这个值直接返回即可。

int binarySearch(int le, int ri, int val)
{
    int mid;
    while (le <= ri) {
        mid = (le + ri) >> 1;
        if (ary[mid] == val)
            return mid;
        else if (ary[mid] > val)
            ri = mid - 1;
        else
            le = mid + 1;
    }
    return -1;
}

2.给定条件的二分查找

举个栗子,求出某个有序序列中最小的比val大的数,第一个等于val的下标等等……

这种二分查找当我们找到一个满足约束条件的值时,我们就尝试着去扩大这个约束极限,使得它更满足我们的条件。我这里可能表述不清楚,比如 ary[idx] > val ,假设序列递增 , 那么可以尝试让idx向右移动。

而对于初学者来说,可能会有两个很困惑的地方。

2.1 最后的二分的结果究竟 取 l ? r ?

当然如果是浮点数二分的话,直接返回 mid 即可

曾经我拿这个问题去问学长,学长说看情况,所以我拖到了现在。
其实我用一句话概括的话,==就是你最后一个满足条件的 mid ==。

我这里举个栗子,查找某个递增序列中最小的比val大的数。

int binarySearch(int le, int ri, int val)
{
    int mid, rlen = ri + 1;
    while (le <= ri) {
        mid = (le + ri) >> 1;
        if (ary[mid] > val) //此时的ary[mid] 满足约束条件
            ri = mid - 1;
        else
            le = mid + 1;
    }
    return ri == rlen ? -1 : ary[ri + 1]; //若val比ary[0]还小,那么ary[0]是满足要求的。
                                          //但如果数组中不存在比val大的数,就要特判一下。
                                          // mid = ri+1 就是在二分过程中最后一个满足约束条件的 idx
}
2.2 在while循环的时候,( le \le ri ) 还是 (le \lt ri)

首先我们可以确定的是,在浮点数二分的时候,这个等于并不会给我们带来太大影响。
而不管是浮点数还是整型数,加了一个等于都能是我们进一步扩大极限的机会。

哦,说白了,其实这个我也不是很清楚,你只要把 = 加上去肯定是没错的……

这个坑以后回来再填。