這是leetcode第374題code
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!leetcode
看完題目,個人第一想法是,遞歸二分查找。因而很快就寫出以下代碼。
Submit獲得結果StackOverFlow,說明遞歸太深了。get
public class Solution extends GuessGame { public int guessNumber(int n) { return guessNumberInternal(1, n); } private int guessNumberInternal(int left, int right) { int middle = (left + right) / 2; int result = guess(middle); switch (result) { case 1: return guessNumberInternal(middle + 1, right); case -1: return guessNumberInternal(left, middle); default: return middle; } } }
那不能用遞歸作二分查找,能不能用循環來代替呢。
下面的代碼Submit後,報錯Time Limit Exceeded。擦竟然超時了。
肉眼看代碼檢查了大半天,發現不粗破綻。it
public class Solution extends GuessGame { public int guessNumber(int n) { int left = 1; int right = n; int guessNumber = 1; while (left <= right) { int middle = (left + right) / 2; int result = guess(middle); boolean find = false; switch (result) { case 1: left = middle + 1; break; case -1: right = middle - 1; break; default: guessNumber = middle; find = true; break; } if (find) { break; } } return guessNumber; } }
int
作加法時溢出了在Java環境下,運行了上面的代碼,才發如今計算middle
時候,left + right
這步計算int
溢出了。
最後,修改代碼以下,Submit,終於Accepted了。io
public class Solution extends GuessGame { public int guessNumber(int n) { int left = 1; int right = n; int guessNumber = 1; while (left <= right) { int middle = left + (right - left) / 2; int result = guess(middle); boolean find = false; switch (result) { case 1: left = middle + 1; break; case -1: right = middle - 1; break; default: guessNumber = middle; find = true; break; } if (find) { break; } } return guessNumber; } }