我们正在玩猜猜游戏。游戏如下:
我选择一个从1到n的数字。您必须猜测我选了哪个号码。
每次您猜错了,我都会告诉您数字是高还是低。
您调用一个预定义的APIguess(int num),它返回3种可能的结果(-1、1或0):
-1:我的电话号码较低
1:我的电话号码较高
0:恭喜!你说对了!
示例:
n = 10,我选择6。
返回6。
Java解决方案
这是一个典型的二进制搜索问题。这是一个Java解决方案。
public int guessNumber(int n) {
int low=1;
int high=n;
while(low <= high){
int mid = low+((high-low)/2);
int result = guess(mid);
if(result==0){
return mid;
}else if(result==1){
low = mid+1;
}else{
high=mid-1;
}
}
return -1;}
我们从这个问题中学到什么?
low +(high-low)/ 2与(low + high)/ 2产生相同的值。但是,第一个表达式不那么昂贵。另外,可以使用以下表达式:
低+((高-低)>> 1)
(低+高)>>> 1
在高和低均为非负的假设下,我们可以肯定地知道最高位(符号位)为零。
因此,高位和低位实际上都是31位整数。
高= 0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824
低= 0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824
将它们加在一起时,它们可能会“溢出”到最高位。
高+低= 1000 0000 0000 0000 0000 0000 0000 0000
= 2147483648作为32位无符号整数
= -2147483648为带符号的32位整数
(高+低)/ 2 = 1100 0000 0000 0000 0000 0000 0000 0000 0000 = -1073741824
(高+低)>>> 1 = 0100 0000 0000 0000 0000 0000 0000 0000 0000 = 1073741824
最后,开发这么多年我也总结了一套学习Java的资料与面试题,如果你在技术上面想提升自己的话,可以关注我,私信发送领取资料或者在评论区留下自己的联系方式,有时间记得帮我点下转发让跟多的人看到哦。