題目:
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.
實(shí)力吐槽!這題其實(shí)本質(zhì)上非常簡(jiǎn)單,簡(jiǎn)單的不要不要的,但是看懂題實(shí)在太費(fèi)勁了,以致于筆者花了一個(gè)小時(shí)丰滑!是一個(gè)小時(shí)!!才把這題的“你砚亭、我”這倆人稱(chēng)看明白!殴玛!
M北臁!滚粟!這就是個(gè)二分查找Q罢獭!凡壤!
不好意思一不小心師太了~~這題確實(shí)理解上容易出問(wèn)題愧沟。接下來(lái)好好說(shuō)思路,避免大家也因?yàn)轭}意影響到編程鲤遥。
思路:
這題的意思是沐寺,我們兩個(gè)人玩猜數(shù)游戲。我從1到n里面選擇一個(gè)數(shù)字盖奈,你來(lái)猜混坞。每次你猜錯(cuò)的時(shí)候呢,我就會(huì)告訴你,你猜大了究孕,或者猜小了啥酱,直到你猜對(duì)為止!類(lèi)似于一些真人秀設(shè)置的游戲規(guī)則厨诸。镶殷。。
注意微酬!這里他告訴我們他已經(jīng)寫(xiě)好了一個(gè)接口guess(int num)绘趋,有三個(gè)返回值:這里我好好翻譯一下
返回-1,代表我們選的數(shù)字比對(duì)方猜的小
返回** 1颗管,代表我們選的數(shù)字比對(duì)方猜的大**
返回** 0**陷遮,代表你猜對(duì)了
還有!他給我們準(zhǔn)備的代碼里:guessNumber(int n)垦江,這個(gè)n是我們?cè)O(shè)置的最大數(shù)帽馋,不是他猜的,是讓我們?cè)O(shè)置好最大數(shù)比吭,他猜數(shù)字绽族,比如他猜了6,那結(jié)果就需要返回6衩藤,不過(guò)中間要有判斷的過(guò)程项秉。
好的我們整理一下我們要做的事情:我們?cè)O(shè)置最大數(shù)字,對(duì)方猜慷彤,我們只能給他反饋他猜大了或者猜小了娄蔼。那他猜的過(guò)程是什么樣的呢?那就要由我們來(lái)編譯了底哗!這里推薦使用折半的方法岁诉。我在代碼里盡量設(shè)置清楚備注。
public class Solution extends GuessGame {
public int guessNumber(int n) {
//如果設(shè)置的最大數(shù)字他直接猜對(duì)了跋选,那就可以直接返回這個(gè)最大數(shù)了
if(guess(n)==0) {
return n;
}
int low = 1;
int high = n;
while(low<high){
//這里的mid不可以使用 int mid = (low+high)/2;
int mid = low + (high-low)/2;
int res = guess(mid);
if(res==0) {
//如果對(duì)方猜對(duì)了直接輸出~
return mid;
}else if(res == 1){
//如果對(duì)方猜的數(shù)字涕癣,比我們?cè)O(shè)置的數(shù)字小前标!那就把mid賦值給low坠韩,讓對(duì)方下次猜的數(shù)變大~
low = mid+1;
}else {
//其余情況只有對(duì)方猜的數(shù)字,比我們?cè)O(shè)置的數(shù)字大炼列!那就把mid賦值給high只搁,讓對(duì)方下次猜的數(shù)變小~
high = mid-1;
}
}
//最后如果在while中,沒(méi)有猜對(duì)(基本上不可能)俭尖!那他猜的這個(gè)數(shù)字氢惋,一定是現(xiàn)在的low了~~
return low;
}
}