前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【leetcode】sqrt(int x)

【leetcode】sqrt(int x)

作者头像
阳光岛主
发布2019-02-19 11:41:28
6210
发布2019-02-19 11:41:28
举报
文章被收录于专栏:米扑专栏米扑专栏米扑专栏

Question:

Implement int sqrt(int x).

Compute and return the square root of x.

Anwser  1: 二分法

class Solution {
public:
    int sqrt(int x) {
        
        if(x < 0) return -1; // assert(x >= 0);
        
        long long x2 = (long long)x;
        long long left = 0;
        long long right = x2;
        long long mid = 0;
        
        while(left <= right){
            mid = left + (right - left) / 2;
            
            if(mid * mid == x2 || (mid * mid < x2 && (mid + 1) * (mid + 1) > x2)){
               return (int)mid;
            } else if(mid * mid < x2){
                left = mid + 1;
            } else{
                right = mid - 1;
            }
        }
    }
};

注意点:

1) 非负数判断,负数没有开平方根

2) 取值范围,mid = left + (right - left) / 2; 可能会超过int最大取值范围,因此需设mid类型为long long(C++没ulong)

Anwser  2: 牛顿迭代法

class Solution {
public:
    int sqrt(int x) {
        if(x < 0) return -1; // assert(x >= 0);
        
        double n = x;
        while(abs(n * n - x) > 0.0001){
            n = (n + x / n) / 2;
        }
        
        return (int)n;
    }
};

注意点:

求a的平方根问题,可以转化为x^2 - a = 0 求x值,进而 abc(x^2 -a) < 0.0001 (0.0001为接近精度)

令 f(x) = x^2 - a, f(x) 即是精度取值范围(无限趋近于0)

对 函数 f(x) 求导:

变换公式,得: 

把 f(x) = x^2 - a 公式求导,导入得: Xn+1 = Xn - (Xn^2 - a) / (2Xn) = Xn - (Xn - a/Xn) / 2 = (Xn + a/Xn) / 2

其中, Xn+1 无限接近于 Xn, 即有: Xn = (Xn + a/Xn) / 2

Anwser  3: 火星人算法

#include <stdio.h>

int InvSqrt(int x)
{
    float x2 = (float)x;
    float xhalf = x2 / 2;
    int i = *(int*) & x2;         // get bits for floating VALUE 
    i = 0x5f375a86 - (i>>1);     // gives initial guess y0
    x2 = *(float*) & i;           // convert bits BACK to float
    x2 = x2 * (1.5f - xhalf * x2 * x2); // Newton step, repeating increases accuracy
    x2 = x2 * (1.5f - xhalf * x2 * x2); // Newton step, repeating increases accuracy
    x2 = x2 * (1.5f - xhalf * x2 * x2); // Newton step, repeating increases accuracy

    printf("\n\n1/x = %d\n", (int)(1/x2));
    return (int)(1/x2);
}



int main(){

    //InvSqrt(65535);
    InvSqrt(10);
    InvSqrt(2147395599);
    InvSqrt(1297532724);

    return 0;

}

说明:

此方法传说非常高效,我是参考别人的float写的int(参数)

在gcc(linux)下编译通过,且测试结果都正确,但在leetcode编译没通过,编译显示信息如下:

Run Status: Internal Error

参考推荐:

leetcode.com

一个Sqrt函数引发的血案

利用牛顿迭代法求平方根

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013年04月13日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档