题目
实现函数 int sqrt(int x).
计算并返回x的平方根(向下取整)
示例1
输入:
2
返回值:
1
分析
第一种:平方数的性质-连续n个奇数相加的结果一定是平方数
如:9 = 1+3+5
16 = 1+3+5+7
可以发现奇数的个数就是开根方的结果。
代码:
public class Solution {
public int sqrt(int x) {
int i = 1;
int res = 0;
while (x >= 0) {
x -= i;
res++;
i += 2;
}
return res - 1;
}
}
第二种:二分法。
下图是证明
⌊
x
⌋
≤
⌊
x
/
2
⌋
\lfloor\sqrt{ x} \rfloor \le \lfloor x /2\rfloor
⌊x⌋≤⌊x/2⌋
public class Solution {
/**
*
* @param x int整型
* @return int整型
*/
public int sqrt (int x) {
// write code here
if(x == 1 || x == 2 || x == 3) {
return 1;
}
int begin = 1;
int end = x / 2;
while(begin <= end) {
int mid = (begin + end) / 2;
int com =x / mid;//注意这里采用的是除法,乘法会发生溢出
//如果相等
if(com == mid) {
return mid;
} else if(com > mid) {
int com2 = x / (mid+1);
if(com2 < mid+1) {
return mid;
} else {
begin = mid + 1;
}
} else {
end = mid - 1;
}
}
return 0;
}
}
第三种:牛顿迭代法,牛顿迭代法常用求函数f(x) = 0的近似解,其迭代方程为:
x
k
+
1
=
x
k
−
f
(
x
k
)
f
′
(
x
k
)
x_{k+1} = x_{k} -\frac {f(x_{k})}{f^{'}(x_{k})}
xk+1=xk−f′(xk)f(xk)
本题中
f
(
r
)
=
r
∗
r
−
x
f(r)=r*r-x
f(r)=r∗r−x,
f
′
(
r
)
=
2
∗
r
f^{'}(r)=2*r
f′(r)=2∗r,故其迭代方程为
x
k
+
1
=
1
2
(
x
k
+
x
x
k
)
x_{k+1} =\frac{1}{2}(x_{k}+\frac{x}{x_{k}})
xk+1=21(xk+xkx)
代码如下:
public int sqrt (int x) {
if( x == 0 || x == 1) {
return x;
}
//初始从x出=处开始迭代
long r = x;
while(x / r < r) {
r = (r + x / r) / 2;
}
return (int) r;
}