leecode/daily/2019-06-27.md
2020-05-22 18:17:19 +08:00

86 lines
1.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 每日一题 - my-sqrt
### 信息卡片
- 时间2019-06-21
- 题目链接:无
> leetcode 上有一个相似的[题目](https://leetcode.com/problems/sqrtx/)
- tag`binary search` `math`
### 题目描述
```
要求不用数学库,求 sqrt(2)精确到小数点后 10 位
```
### 参考答案
1. 二分法
这个解法比较直接,就是普通的二分。
通过每次取中间值进行比较我们可以舍去一半的结果。时间复杂度logn
参考代码:
```js
function sqrt(num) {
if (num < 0) return num;
let start = 0;
let end = num;
let mid = num >> 1;
const DIGIT_COUNT = 10;
const PRECISION = Math.pow(0.1, DIGIT_COUNT);
while (Math.abs(+(num - mid * mid).toFixed(DIGIT_COUNT)) > PRECISION) {
mid = start + (end - start) / 2.0;
if (mid * mid < num) {
start = mid;
} else {
end = mid;
}
}
return mid;
}
```
2. 牛顿迭代法
这种方法是牛顿发明的,比较巧妙。
其实上述问题可以转化为x^2-a = 0求x的值。其实也就是曲线和y轴交点的横坐标。
我们可以不断用f(x)的切线来逼近方程 x^2-a = 0的根。
根号a实际上就是x^2-a=0的一个正实根由于这个函数的导数是2x。
也就是说,函数上任一点(x,f(x))处的切线斜率是2x。
那么x-f(x)/(2x)就是一个比x更接近的近似值。代入 f(x)=x^2-a得到x-(x^2-a)/(2x),也就是(x+a/x)/2。
![2019-06-27](../assets/daily/2019-06-27.gif)
(图片来自Wikipedia)
参考代码:
```js
function sqrtNewton(n) {
if (n <= 0) return n;
let res;
let last;
const DIGIT_COUNT = 10;
const PRECISION = Math.pow(0.1, DIGIT_COUNT);
res = n;
while (Math.abs(last - res) > PRECISION) {
last = res;
res = (res + n / res) / 2;
}
return res;
}
```
### 其他优秀解答
```
暂无
```