请问老师为何r要取data.length呢

请问老师为何r要取data.length呢

图片描述
上图红框中的r取值为何要多加1呢?r为何不取 data.length-1, 而要取data.length 呢?如果target大于整个数组的所有值的时候,相当于没找到,返回-1 不行么?

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

2回答
假蛙工程师 2021-11-26 17:23:15

我试了:

// 在arr[l, r]中查找大于target的最小值
private static <E extends Comparable<E>> E upper3(E[] data, int l, int r, E target){
    
    // r = data.length 的情况
    if(l == r){
        if(l == data.length)
            return null;
        return data[l];
    }

    // 区别在于:上面的代码l == r就可以表示找到了大于target的最小值
    // 下面的代码l == r还需要分类讨论。假设target = 98, 那么l == r可以表示找到了,应该返回98
    // 假设target = 100,那么l == r,表示l一直向右挪动,正好到了r,它还想继续向右挪动。l == r的语义不统一
    
    // r = data.length - 1的情况
    if(l == r){
        if(data[l].compareTo(target) <= 0)
            return null;
        return data[l];
    }

    // 这部分代码一样
    int mid = l + (r - l) / 2;
    if(data[mid].compareTo(target) <= 0){
        return upper3(data, mid + 1, r, target);
    }else{
        return upper3(data, l, mid, target);
    }


}


liuyubobobo 2021-02-04 04:43:07

首先,使用你的想法,也是可以实现 upper 的。但还是有一些细节需要处理。我强烈建议你按照自己的想法,实现一版 upper,体会一下。


在课程的代码中,我们让 r = data.length,你可以想象成,我们设置了一个虚拟的元素,这个元素是正无穷。所以,当我们要查找的目标 t 比数组的最大元素还要大的时候,就会找到这个位置。


而这个位置因为在 data.length - 1 的右端,就可以保证在我们查找的过程中,如果当前的元素比 t 小,我们继续往右找是正确的。如果当前的元素比 t 小,按照我们的逻辑,我们就会继续往右找。直到找到整个数组最右面一个元素的右面了,还没有,说明没有找到。这是逻辑自洽的。而 -1 在整个数组的左面。(这也是为什么,对于 lower 来说,我们反向的,是设置 l = -1, r = data.lenth - 1)


最后,在这个算法的一些应用中,这样设置,也是语义上更方面的。比如我们要想直到整个数组 <= t 的元素有多少个?我们只需要找到大于 t 的第一个元素索引 i,这个 i 的值,就是 <= t 的元素个数。如果所有元素都 <= t,我们的算法返回的就是 data.length,那么 data.length,就是整个数组中 <= t 的元素个数。这样定义,我们不需要对算法返回一个 -1 做特殊的处理。


为了理解这个与以上的方便之处,我建议你多看一看 leetcode 上用二分搜索处理的问题,感受会更强烈。


继续加油!:)

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
算法与数据结构
  • 参与学习       2583    人
  • 解答问题       1082    个

慕课网算法名师Liuyubobobo,5年集大成之作 从0到工作5年,算法与数据结构系统解决方案

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师