比如:Java的世界里Int类型最大值是: Integer.MAX_VALUE = 2147483647
System.out.println("Integer.MAX_VALUE = " + Integer.MAX_VALUE);
int left = 2147483647;
int right = 2147483647;
int result = (left+right)/ 2;
System.out.println("result = " + result);
int result2 = left+(right-left)/2;
System.out.println("result2 = " + result2);
此时可以在脑中运行一遍,看是否与下面电脑运行的结果相符?
Integer.MAX_VALUE = 2147483647
result = -1
result2 = 2147483647
先看一下的例子
int i = 12;
int d = 16;
int res = i + ((d - i) >> 1);
System.out.println("res = " + res);
int e = 16;
int res2 = i + (e - i) >> 1;
System.out.println("res2 = " + res2);
实际运行结果如下:
res = 14
res2 = 8
int le = -10;
int ri = -3;
int ave1 = (le + ri) / 2;
int ave2 = le + (ri - le) / 2;
System.out.println("ave1 = " + ave1);
System.out.println("ave2 = " + ave2);
结果:
ave1 = -6
ave2 = -7
如果要想两个公司结果保持一致,可以这样写,代码如下:
int ave3 = ri + (le - ri) / 2;
System.out.println("ave3 = " + ave3);
运行结果如下:
ave3 = -6
int x = -9;
int aa = x / 2;
int bb = x >> 1;
System.out.println("aa = " + aa);
System.out.println("bb = " + bb);
实际运行结果:
aa = -4
bb = -5
二分定义
二分查找()百度百科):二分查找也称折半查找()Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列.
上述的定义只是狭义上的二分查找定义,在上述定义中提到了一个概念:有序,但实际上,我们只需要让线性表满足二段性即可使用二分.
二段性那么,什么是二段性呢
所谓二段性,就是在线性表中有一个元素,使得该元素的左侧满足性质1,右侧满足性质2。
举个例子,有一个数组nums = 4, 5, 6, 7, 0, 1, 2,该数数组原本是严格递增的,但是被按照某个点旋转了一次。现在我们需要找出该数组的原始起点(当然,直接遍历一遍是一种有效但并不优美的做法)。在这例子中,起点当然是0了,并且我们通过观察可以发现,0的左侧满足所有的元素都大于等于nums0 = 4(性质1),而 0及其右侧元素都小于nums0 = 4(性质2)。那么此时,元素0就是让这个线性表具有二段性的元素之一(为什么说之一呢,因为例如7也能使该线性表具有二段性)。
为什么具有二段性就能使用二分呢?
还是拿上述例子进行说明,我们既然清楚了我们需要查找的元素具有二段性,那么,我们是否可以利用这个性质缩小查询范围以不断逼近并最终查询到这个元素呢?
利用二段性实现二分答案是肯定的。每一次,我们取整个线性表的中间元素(下标记为mid),判断numsmid满足性质1还是性质2。
如果满足性质1,则说明numsmid在目标元素的左侧,此时我们将区间左端点(l)移动到mid + 1(因为此时我们可以明确的知道numsmid并不是我们需要的元素)
如果满足性质2,则说明numsmid就是目标元素或是在目标元素右侧,此时我们将区间右端点移动到mid **
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。