java - 二分查找权应该是 nums.length 还是 nums.length - 1?
问题描述
我总是对二进制搜索右边界感到困惑。例如,如果我们想在有序数组中找到目标的最后一个索引,代码应该是:
public int binarySearchLarger(int[] nums, int target) {
int l = 0;
int r = nums.length - 1;
while (l < r) {
int m = l + (r - l + 1) / 2;
if (nums[m] < target) l = m;
else if(nums[m] > target) r = m - 1;
else l = m;
}
if (nums[l] == target) return l;
else return -1;
}
但是我看到很多帖子说如果我们想要while(l<r),那么r应该是nums.length,在这种情况下,代码变成:
public int binarySearchLarger(int[] nums, int target) {
int l = 0;
int r = nums.length;
while (l < r) {
int m = l + (r - l + 1) / 2;
if (nums[m] < target) l = m;
else if(nums[m] > target) r = m - 1;
else l = m;
}
if (nums[l] == target) return l;
else return -1;
}
但是在这种情况下,if (nums[m] < target) l = m;
会抛出arrayindexoutofbound异常。我的问题是:我们应该什么时候使用r = nums.length - 1
,什么时候应该使用r = nums.length?
解决方案
我这样做:
int findEndIndex( vector<int> &nums, int target ){
int l = 0, r = nums.size() - 1;
while( l < r ){
int m = (l + (r - l) / 2) + 1;
if( nums[m] == target )
l = m;
else if( nums[m] < target )
l = m + 1;
else
r = m - 1;
}
return l >= nums.size() || nums[l] != target ? -1 : l;
}
推荐阅读
- file - 如何使用java从Android 10的外部存储中获取所有带有FileName的PDF文件Uri
- azure - Azure 持久函数:获取执行时间
- ios - 如何使用 CloudKit 保存图像?
- ios - Swift Realm,当应用程序在后台时,写入数据库在appdelegate中不起作用
- javascript - 如何将某些 Date 对象转换为德国的相应时间?
- xml - 针对 XSD 架构验证 XML
- node.js - 通过 Admin SDK for Google Cloud Identity Platform 创建默认提供程序
- javascript - 在 apache 服务器上部署 React (3000) 和 Express (8000) 应用程序
- javascript - 使用 jest 比较两个文件的内容
- c++ - 在 C++11 中,可以在同一行声明全局变量和函数原型吗?