Reference: http://blog.csdn.net/lbyxiafei/article/details/9375735
題目:
Implement int sqrt(int x)
.
Compute and return the square root of x.
題解:
這道題很巧妙的運用了二分查詢法的特性,有序,查詢pos(在這道題中pos=value),找到返回pos,找不到返回鄰近值。
因為是求數x(x>=0) 的平方根, 因此,結果一定是小於等於x且大於等於0,所以用二分查詢法肯定能搜到結果。
以每一次的mid的平方來與target既數x相比:
如果mid*mid == x,返回mid;
如果mid*mid < x,那麼說明mid過小,應讓low = mid+1,在右邊繼續查詢
如果mid*mid > x,那麼說明mid過大,應讓high = mid-1,在左邊繼續查詢
若x無法開整數根號(在上述查詢中沒有找到),那麼我們仍然可以利用之前對二分查詢法總結的技巧,當target值不在陣列中,low指向大於target的那個值,high指向小於target的那個值,由於我們需要向下取整的結果,所以我們返回high指向的值(這裡high指向的值和high的值是同一個值),這個值就是所求得最接近起開根號結果的整數值。
因為leetcode的test case x=2147395599,在算mid*mid的時候造成溢位,所以mid不能使用int型來接,要使用long型防止溢位(Java中Integer型的範圍:-2147483648 到2147483648)
程式碼為:
1 public int sqrt(int x) {
2 int low = 0;
3 int high = x;
4 while(low<=high){
5 long mid = (long)(low + high)/2;
6 if(mid*mid < x)
7 low = (int)mid + 1;
8 else if(mid*mid > x)
9 high = (int)mid - 1;
10 else
11 return (int)mid;
12 }
13 return high;
14 }
2 int low = 0;
3 int high = x;
4 while(low<=high){
5 long mid = (long)(low + high)/2;
6 if(mid*mid < x)
7 low = (int)mid + 1;
8 else if(mid*mid > x)
9 high = (int)mid - 1;
10 else
11 return (int)mid;
12 }
13 return high;
14 }