您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法[LeetCode]——sqrt(x)

2014-04-14 12:05 751 查看


Sqrt(x)



Implement
int sqrt(int x)
.

Compute and return the square root of x.

方法一:折半分析法


/* *折半法分析 *结论:任何一个大于0数的平方根的平方根都大于等于1,小于x/2+1;
*编程:可以使用类似折半查找的方式
*效率:高
* */

class Solution{
public:
int sqrt(int x){
if(x==0)return 0;
if(x==1)return 1;

double low,mid,high;
double v,n=x;  //算开方,内部使用double型

low=1,high=n/2+1;
while(low<=high){
mid=low+(high-low)/2;
if(mid*mid>n)
high=mid;   //是连续的数,不是离散的下标,使用high=mid-1,low=mid+1会漏过连续的小数数据。
if(mid*mid<n)
low=mid;
if(int(mid*mid)==int(n))
return (int)mid;
}
return int(low+(high-low)/2);
}
};



方法二:牛顿迭代法

牛顿迭代法求平方根(n次根):

求n的平方根,先假设一猜测值X0 = 1,然后根据以下公式求出X1,再将X1代入公式右边,继续求出X2…通过有效次迭代后即可求出n的平方根,Xk+1 。



简单推导:
假设f(x)是关于X的函数:



求出f(x)的一阶导,即斜率:



简化等式得到:



然后利用得到的最终式进行迭代运算直至求到一个比较精确的满意值,为什么可以用迭代法呢?理由是中值定理(Intermediate Value Theorem):
如果f函数在闭区间[a,b]内连续,必存在一点x使得f(x)
= c,c是函数f在闭区间[a,b]内的一点
我们先猜测一X初始值,例如1,当然地球人都知道除了1本身之外任何数的平方根都不会是1。然后代入初始值,通过迭代运算不断推进,逐步靠近精确值,直到得到我们主观认为比较满意的值为止。例如要求768的平方根,因为252
= 625,而302 = 900,我们可先代入一猜测值26,然后迭代运算,得到较精确值:27.7128。
回到我们最开始的那个”莫名其妙”的公式,我们要求的是N的平方根,令x2 = n,假设一关于X的函数f(x)为:
f(X) = X2 - n
求f(X)的一阶导为:
f'(X) = 2X
代入前面求到的最终式中:
Xk+1 = Xk - (Xk2- n)/2Xk
化简即得到我们最初提到的那个求平方根的神奇公式了:



实现代码:
/*
* 牛顿迭代法求平方根(n次根):
* 根据斜率求法:x<k+1>= 1/2(x<k>+n/x<k>)
* 效率:更高
* */

class Solution{
public:
int sqrt(int x){
double n=x;i            //算开方,内部都使用double型
if(n==1)return 1;
double v=1;  //初始:x1=1
int v_pre;
do                 //理论上循环次数越多,越精确,但是,题目要求知道整数位,所以当整数位不再变化时即停止。
{
v_pre=(int)v;
v=1.0/2*(v+n/v);
}while(v_pre!=(int)v);  //整数位不再变化,(前后两次整数位都没有变化)
return (int)v;
}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: