请问老师为何r要取data.length呢
上图红框中的r取值为何要多加1呢?r为何不取 data.length-1, 而要取data.length 呢?如果target大于整个数组的所有值的时候,相当于没找到,返回-1 不行么?
正在回答 回答被采纳积分+1
我试了:
// 在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); } }
首先,使用你的想法,也是可以实现 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 星