简单地试了一下二分法,也要注意精度的问题
class Solution {
public:
int mySqrt(int x) {
int left = 0, right = x;
while (left < right) {
int mid = left + (right - left) / 2;
// cout << mid << endl;
if (long(mid) * mid == x) {
return mid;
} else if (long(mid) * mid < x) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return long(left) * left > x ? left - 1:left;
}
};
看到有牛顿迭代法的解法,牛顿迭代法: https://zh.wikipedia.org/wiki/%E7%89%9B%E9%A1%BF%E6%B3%95
class Solution {
public:
// 牛顿迭代法 X[n+1] = 1/2 * (X[n] + a/X[n]), a is x^2
// 单纯的整数开方数直接二分迭代
int mySqrt(int x) {
if (x == 0) return 0;
int y = x/2;
while (true) {
y = max(y, 1);
long long k1 = 1L * y * y;
long long k2 = 1L * (y+1)*(y+1);
if (k1 <= x && k2 > x) { return y; }
y = (y + x / y) / 2;
}
return y;
}
};
还有个思路跟二分法一样,但是用位操作的解法,值得记录一下:
public int sqrt(int x) {
long ans = 0;
long bit = 1l << 16;
while(bit > 0) {
ans |= bit;
if (ans * ans > x) {
ans ^= bit;
}
bit >>= 1;
}
return (int)ans;
}