1. 题目描述
We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I’ll tell you whether the number is higher or lower.
You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0):
-1 : My number is lower
1 : My number is higher
0 : Congrats! You got it!
Example:
n = 10, I pick 6.
Return 6.
题目大意,从1到n中任意挑选一个数,你需要猜想这个数,题目给定一个guess函数,返回有三种可能,第一种,当你猜的数字<他选的数字时返回1,第二种,当你猜的数字>他选的数字时,返回-1,当正好猜着了的时候,返回0。这个需要仔细的读一读,题目中My number代表着他选的数字,不要弄错哦,我是不会说我弄错了然后还调试半天找不出错误…
2. 解题思路
题目可以被简化为一个查找的问题,而查找算法中,效率比较好的,时间比较平均的算法就是二分查找。二分查找的主要思路:给定一个排序好的序列,一个最小值,一个最大值,计算中间值,当中间值为要查找的值时,返回该值。如果不是要查找的值,查看要查找的值是在mid的左边还是在mid的右边,修改最大最小值,重复上面的过程。为了提高查找效率,我才用了一次比较三个的方式,看看最小值,最大值,和中间值是否为要查找的值。
告诫自己:二分查找这么简单的事情请能用循环就不要用递归,会造成栈溢出的。
3. Code
// Code1:使用了递归的二分查找,栈溢出T T
public class Solution extends GuessGame {
// 二分查找变体
public int guessNumber(int n) {
if(n <= 0)
{
return -1;
}
return fun(1, n);
}
public int fun(int low, int high)
{
if(low > high)
{
return -1;
}
if(guess(low) == 0)
{
return low;
}else if(guess(high) == 0)
{
return high;
}
int mid = (int)(low+high)/2;
int iguess = guess(mid);
if(iguess == 0)
{
return mid;
}
else if(iguess >= 1)
{
return fun(low + 1, mid - 1);
}
else if(iguess <= -1)
{
return fun(mid + 1, high - 1);
}
else
{
return -1;
}
}
}
// 使用循环的二分查找
/* The guess API is defined in the parent class GuessGame.
@param num, your guess
@return -1 if my number is lower, 1 if my number is higher, otherwise return 0
int guess(int num); */
public class Solution extends GuessGame {
// 二分查找变体
public int guessNumber(int n) {
if(n <= 0)
{
return -1;
}
int low = 1, high = n;
while(low <= high)
{
if(guess(low) == 0) return low;
if(guess(high) == 0) return high;
//int mid = (int)((low + high)/2);
int mid = low + (high-low)/2; // low+high会造成integer的溢出
int iguess = guess(mid);
if(iguess == 0)
{
return mid;
}
else if(iguess >= 1)
{
low = mid + 1;
high = high - 1;
}
else if(iguess <= -1)
{
high = mid - 1;
low = low + 1;
}
}
return -1; // 没找到结果
}
}