algorithm - 在二分搜索中确定中间值
问题描述
我在hackerearth上练习一个问题:
在这个问题中,我编写了一个使用过的二进制搜索代码:
整数中间=(低+高)/2
我的循环卡在这里,所以在某些情况下我得到了 TLE。意识到问题(反复选择低)后,我将中间更改为低 +(high-low+1)/2,并且通过此更改,整个测试用例都通过了。(代码 1)
我也做过一个类似的问题,我使用 (low+high)/2 并且也通过了所有测试用例。
我的问题是我们如何决定我们将如何选择中路?
PS:这些是练习题,现在解决了(由我)
代码1
public static boolean subarray(int mid,long x,long[] sum,int[] a){
int n=a.length;
for(int i=0;i<n-mid+1;i++){
if(sum[mid+i-1]-sum[i]+a[i]>x){
return false;
}
}
return true;
}
public static void binarysearch(long[] sum,int [] a,long x){
int low=1;
int high=a.length;
while(low!=high){
int mid=low+ (high-low+1)/2; //passed
//int mid=(low+high)/2; did n't PASS
if(!subarray(mid,x,sum,a)){//if some greater then x
high=mid-1;
}
else{
//if some less then x okay but can go for more
low=mid;
}
}
System.out.println(low);
}
代码2
public static long binarysearch(long[] a,long x,long[] L,long[] R){
//find first index >= x
BufferedOutputStream out=new BufferedOutputStream(System.out);
int low=0;
int high=a.length;
while(low!=high){
int mid=(low+high)/2;
if(a[mid]<x){
low=mid+1;
}
else{
high=mid;
}
}
long ans=L[low]+x-1;
if(low!=0){
ans=L[low]+x-a[low-1]-1;
}
return ans;
}
解决方案
这种技术:
low + (high - low) /2
主要用于避免整数溢出。
由于 mid 是数值类型的一个实例,它可以容纳的值有一个上限。低和高的总和可能会超过此最大值,从而导致溢出和不可预测的结果。即使低和高都是合法值(即正和高>=低),也会发生这种情况。
对于 high 和 low 的合法值,表达式 mid = low + (high - low) / 2 永远不会溢出,并且总是会给出所需的结果。
例子:
int low = 1170105034
int high = 1347855270
(low + high) / 2 //outputs -888503496
low + (high - low) / 2 //outputs 1258980152
推荐阅读
- reactjs - 删除突变后从服务器重新获取数据
- python - Python 展平深层嵌套 JSON
- django - 为嵌套的 JSON 数据编写正确的循环
- python - Python pandas:如何将多个 groupby 列之一排序为特定/自定义顺序?
- c++ - 从 C++ 中的数字中删除一个数字
- web-scraping - 如何从连续滚动的网站加载信息以使用 beautifulsoup 进行抓取?
- python - 如何在 flask_restful 中访问反序列化和验证对象的值
- python - 使用Python解压缩多文件夹目录时没有这样的密钥错误
- postgresql - 使用 bytea 作为表索引和连接条件
- json - 如何在HANA DB中返回没有双引号的JSON字符串子查询?