LeetCode | Sqrt(x)

来源:互联网 发布:艾瑞咨询好吗 知乎 编辑:程序博客网 时间:2024/06/06 06:46


Implement int sqrt(int x).

题目解析:

求开方根,只是求解整数,比较容易,如果求解double类型的,就要考虑精度问题。


题型一:求整数根

先讲解求解整数根的情况。

题目简单,可以直接让i从0...x的增加,比如要能取到x不然,x为2的时候,根据实现会报错。某些时候也可以更精确到x/2。但由于是递增,不用考虑那么详细。

不过这里会碰到问题,就是越界的问题,有些时候,用long long都不好用,还得用unsigned long long才行,如下面:

方案一:

采用二分法:

int sqrt(int x) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        unsigned long long begin = 0;        unsigned long long end = (x+1)/2;        unsigned long long mid;        unsigned long long tmp;        while(begin < end)        {            mid = begin + (end-begin)/2;            tmp = mid*mid;            if(tmp==x)return mid;            else if(tmp<x) begin = mid+1;            else end = mid-1;        }        tmp = end*end;        if(tmp > x)            return end-1;        else            return end;    }

方案二:

但是为什么非要用相乘呢?通过判断mid > x/mid等条件也能得到相应答案。这样就避免了大数相乘的问题。代码如下:

class Solution {public:    int sqrt(int x) {        if(x < 0)            return -1;        if(x==0 || x==1)            return x;        for(int i = 1;i <= x;i++){            if(i == x/i){                return i;            }else if(i > x/i)                return i-1;        }    }};

这个方法能很好的扩展到其他问题,应该记住。


方案三:

这就涉及到用几何问题去解决。但这个里面用double类型的数当中间值,来精确求解。

牛顿迭代法


   为了方便理解,就先以本题为例:

   计算x2 = n的解,令f(x)=x2-n,相当于求解f(x)=0的解,如左图所示。

   首先取x0,如果x0不是解,做一个经过(x0,f(x0))这个点的切线,与x轴的交点为x1

   同样的道理,如果x1不是解,做一个经过(x1,f(x1))这个点的切线,与x轴的交点为x2

   以此类推。

   以这样的方式得到的xi会无限趋近于f(x)=0的解。

   判断xi是否是f(x)=0的解有两种方法:

   一是直接计算f(xi)的值判断是否为0,二是判断前后两个解xi和xi-1是否无限接近。

 

经过(xi, f(xi))这个点的切线方程为f(x) = f(xi) + f’(xi)(x - xi),其中f'(x)为f(x)的导数,本题中为2x。令切线方程等于0,即可求出xi+1=xi - f(xi) / f'(xi)。

继续化简,xi+1=xi - (xi- n) / (2xi) = xi - xi / 2 + n / (2xi) = xi / 2 + n / 2xi = (xi + n/xi) / 2。

有了迭代公式xi+1= (xi + n/xi) / 2,程序就好写了。关于牛顿迭代法,可以参考wikipedia以及百度百科

int sqrt(int x) {// Start typing your C/C++ solution below        // DO NOT write int main() function        if (x ==0)            return 0;        double pre;        double cur = 1;        do        {            pre = cur;            cur = x / (2 * pre) + pre / 2.0;        } while (abs(cur - pre) > 0.00001);        return int(cur);    }


题型二:double型平方根

方案一:

对于小数有个精度的问题,那么定义0.000001范围内就认为两个数相等。

public double sqrt(double x) {if (x < 0) return -1;double left  = 0;double right = (x < 1) ? 1 : x;double maxDiff = 0.000001;do {double mid = left + (right - left) / 2;if (Math.abs(x - mid * mid) <= maxDiff) {return mid;} else if (x - mid * mid < 0) {right = mid;} else {left = mid;}} while (true);}

可以参考链接:http://blog.csdn.net/maqingli87/article/details/8051610

里面有好几种方法。





0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 计算题总是出错怎么办 数学老是计算错误怎么办? 苗木抵扣计算错误怎么办 表格中计算错误怎么办 孩子电视瘾太大怎么办 孩子考试前失眠怎么办 孩子上网瘾了怎么办 孩子考试差家长怎么办 手指肿痛有脓包怎么办 手指脓出来红肿怎么办 手指提重物发麻怎么办 小孩拧伤了怎么办 从小就成绩差怎么办 孩子考试总马虎怎么办 上课不认真怎么办初中 对学习兴趣不大怎么办 小学生做作业粗心大意怎么办 小学生考试总是粗心大意怎么办 脚趾内侧长鸡眼怎么办 五岁宝宝胆小怎么办 孩子偏食挑食老师怎么办 九岁孩没有耐心怎么办 孩子学习太粗心怎么办 害怕自己变疯怎么办 工作太粗心了怎么办 粗心的宝宝该怎么办 孩子身上起范怎么办 又笨又内向怎么办 学生做试卷马虎怎么办 小孩子学习态度不好怎么办 孩子学习态度差怎么办 小孩学习态度不好怎么办 孩子数学老粗心怎么办 二年级学生粗心怎么办 学生做题粗心怎么办 小学生做题粗心怎么办 审题总是不认真怎么办 好学生批评了怎么办 地生会考没考好怎么办 一年级孩子抄作业怎么办 孩子抄作业慢怎么办