题目题目链接:
https://leetcode-cn.com/problems/sqrtx/
方法:给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
示例 1:
输入:x = 4
输出:2
示例 2:输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
第一次代码:二分法
class Solution {
public int mySqrt(int x) {
int mid = x / 2;
while(true){
if(mid * mid <= x && (mid+1) * (mid+1) > x)
return mid;
else if(mid * mid > x)
mid /= 2;
else
mid += 1;
}
}
}
改进代码1:报错:输入2147395599,输出1073788163,预期输出46339
原因:int类型最大值 ,当mid*mid时有一部分超出了int的范围。
class Solution {
public int mySqrt(int x) {
long mid = x / 2;
while(true){
if(mid * mid <= x && (mid+1) * (mid+1) > x)
return (int)mid;
else if(mid * mid > x)
mid /= 2;
else
mid += 1;
}
}
}
改进代码2:执行用时:19 ms 内存消耗:39.1MB
// 二分法,算术平方根一定在 [1,x] 之间,所以以 1 ~ x 为界
class Solution {
public int mySqrt(int x) {
long first = 1, last = x, mid = 0, ans = 0;
while(first <= last){
mid = (first + last) / 2;
if(mid * mid <= x){
ans = mid;
first = mid + 1;
}
else
last = mid - 1;
}
return (int)ans;
}
}
改进代码3:执行用时:1 ms 内存消耗:39.1 MB
// 二分法,算术平方根一定在 [1,x] 之间,所以以 1 ~ x 为界
// 这里用 x/mid 来替代 mid*mid ,使得int类型也足够了,不需要long类型
class Solution {
public int mySqrt(int x) {
int first = 1, last = x, mid = 0, ans = 0;
while(first <= last){
mid = (first + last) / 2;
if(x / mid >= mid){
ans = mid;
first = mid + 1;
}
else
last = mid - 1;
}
return ans;
}
}
牛顿迭代法:
// 牛顿迭代法 (x0 = (c + c / x) / 2 )== c ? (return c) : (c = x0)
class Solution {
public int mySqrt(int x) {
double c = x, x0 = 0;
if(x == 0) // 分母为0时单独考虑
return 0;
while(true){
x0 = (c + x/c) / 2;
if(c == x0)
return (int)c;
else
c = x0;
}
}
}
答案链接:https://leetcode-cn.com/problems/sqrtx/solution/niu-dun-die-dai-fa-by-loafer/
类似题目:367. 有效的完全平方数



