题目
我们正在玩一个猜数游戏,游戏规则如下:
我从 1 到 n 选择一个数,你猜我选择了哪个数。
每次你猜错了,我会告诉你你猜的数是大了还是小了。
你可以调用预定义 API guess(int num),它有三个不同的返回值:
-1:我选择的数比你猜的小,即是你猜大了
1:我选择的数比你猜的大,即是你猜小了
0:恭喜,你猜中了!
示例:
n = 10,我选择 6,你的函数应该返回 6。
难度:容易
编程语言:C++
分析
程序框架为:
1 2 3 4 5 6 7 8 9 10 11
| int guess(int num); class Solution { public: int guessNumber(int n) { } };
|
我的思路是,low = 1,high = n,每次猜错就减小一半的范围。每次猜的数是 [low, high] 的中间值 mid。如果 mid 小了,则下次需要往大猜,low = mid,mid = (low + high) / 2。如果 mid 大了,则下次需要往小猜,high = (low + high) / 2,mid = (low + high) / 2。猜到最后会剩下两个相邻的数,一奇一偶。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| #include <frequently-used-code-snippets.h> #define GUESS_LOWER_NEXT_TIME -1 #define GUESS_HIGHER_NEXT_TIME 1 #define GOT_IT 0 #define RANGE 2147483647 #define PICK 2147483647 int guess(int num) { if (PICK < num) { return -1; } if (PICK > num) { return 1; } return 0; } class Solution { public: int guessNumber(int n) { int low = 1; int high = n; int myGuess = getAverage(low, high); bool twoNumsLeft = false; int result = guess(myGuess); while (result != GOT_IT) { if (result == GUESS_LOWER_NEXT_TIME) { high = getAverage(low, high); } else { if (twoNumsLeft) { myGuess = high; break; } else { low = myGuess; } } if (high - low <= 1) { twoNumsLeft = true; } myGuess = getAverage(low, high); result = guess(myGuess); } return myGuess; } private: int getAverage(int low, int high) { return low + (high - low) / 2; } }; int main() { Solution sol; cout << sol.guessNumber(RANGE) << endl; }
|
提交到 Leetcode,Accepted! :),运行时间为 0ms。