Implement int sqrt(int x).

Compute and return the square root of x.

转自:http://blog.csdn.net/doc_sgl/article/details/12404971

实际面试遇到的题目可能不是对一个整数开方,而是对一个实数。方法和整数其实是一致的,只是结束条件换成左界和右界的差的绝对值小于某一个epsilon(极小值)即可。在C++中我们需要通过两个数的绝对值差小于某个极小值来判断两个double的相等性。实际上两个double因为精度问题往往是不可能每一位完全相等的。

1. 二分法:

这道题一看到函数的定义int sqrt(int x)都是int就高兴了,直接二分吧。但是要注意,即使用long long都TM越界,还要用unsigned long long。最后返回值还要再检查一下。

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

2. 牛顿迭代法


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

计算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以及百度百科

class Solution {
public:
int mySqrt(int x) {
if (x ==)
return ;
double pre;
double cur = ;
do
{
pre = cur;
cur = x / ( * pre) + pre / 2.0;
} while (abs(cur - pre) > 0.00001);
return int(cur); }
};
float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating VALUE
i = 0x5f375a86- (i>>); // gives initial guess y0
x = *(float*)&i; // convert bits BACK to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
return x;
}

Sqrt(x)——二分法,防越界的更多相关文章

  1. saturate_cast防越界函数

    CV_IMAGE_ELEM(img2,uchar,i,j*3+c)=saturate_cast<uchar>(alpha*( CV_IMAGE_ELEM(img,uchar,i,j*3+c ...

  2. 【经典面试题】实现平方根函数sqrt

    本文将从一道经典的面试题说起:实现平方根函数,不得调用其它库函数. 函数原型声明例如以下: double Sqrt(double A); 二分法 二分法的概念 求,等价于求方程的非负根(解).求解方程 ...

  3. 开博第一篇:DHT 爬虫的学习记录

    经过一段时间的研究和学习,大致了解了DHT网络的一些信息,大部分还是参会别人的相关代码,一方面主要对DHT爬虫原理感兴趣,最主要的是为了学习python,大部分是别人的东西原理还是引用别人的吧 DHT ...

  4. CODEVS 2055 集合划分

    [题目描述] 对于从1到N(1<=N<=39)的连续整数集合,划分成两个子集合,使得每个集合的数字之和相等. 举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,他们每个的所有数字 ...

  5. C++Primer第5版学习笔记(一)

    C++Primer第5版学习笔记(一) 第一.二章的重难点内容        这个笔记本主要记录了我在学习C++Primer(第5版,中文版)的过程中遇到的重难点及其分析.因为第一.二章都比较简单,因 ...

  6. 快速排序 partition函数的所有版本比较

    partition函数是快排的核心部分 它的目的就是将数组划分为<=pivot和>pivot两部分,或者是<pivot和>=pivot 其实现方法大体有两种,单向扫描版本和双向 ...

  7. FJUT寒假作业涨姿势题解

    题意非常简单易懂,对于涨姿势0,数据非常小,比较容易想到的是直接循环暴力解题完成任务.把数据放入数组arr,循环i,j控制所有区间算和.结果记入vis. 到了涨姿势1,2,3,我们观察数据变化,发现数 ...

  8. 洛谷P2569 股票交易

    题目传送门https://www.luogu.org/problemnew/show/P2569 第一眼看题就觉得是个dp ,然后看到2000的范围,hmm大概是个n^2的2维dp 开始设状态,第一维 ...

  9. P1282 多米诺骨牌

    P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S ...

随机推荐

  1. sass的颜色函数

    sass中有些非常实用的颜色处理函数,总结如下 1.颜色加深或变浅 lighten($color,$amount) //颜色变浅 darken($color,$amount) //颜色加深 例如: l ...

  2. ywy_c_asm题

    未知出处 题意: 定义一个无穷长的数列,满足以下性质:$1.X_{2n}=-{X_{n}}$ $2.X_{2n}=(-1)^{(n+1)}*X_{n}$ $3.X_{2n-1}=(-1)^{(n+1) ...

  3. 【图论】tarjan的离线LCA算法

    百度百科 Definition&Solution 对于求树上\(u\)和\(v\)两点的LCA,使用在线倍增可以做到\(O(nlogn)\)的复杂度.在NOIP这种毒瘤卡常比赛中,为了代码的效 ...

  4. 解决无法安装cnpm,cnpm卡顿问题

    # 注册模块镜像 npm set registry https://registry.npm.taobao.org # node-gyp 编译依赖的 node 源码镜像 npm set disturl ...

  5. selenium - 获取断言信息

    断言:通过脚本提取相应元素的数值,将实际结果与预期结果进行比较.通常获取title,URL,text等信息进行断言. from selenium import webdriver from time ...

  6. Indexing GROUP BY

    SQL databases use two entirely different group by algorithms. The first one, the hash algorithm, agg ...

  7. Linux系统iptables查看、设置、保存、备份和恢复

    不同linux系统,相关软件是否安装,会让iptables的某些命令不能执行,这里收集了大多数iptables命令,不管是Ubuntu还是Centos,都能找到相关的修改.查询.保存命令. 仅允许某些 ...

  8. RabbitMQ 命令

    1.RabbitMQ 服务启动与关闭 同时启动RabbitMQ 节点和erlang服务 普通方式启动./rabbitmq-server守护线程方式启动./rabbitmq-server –detach ...

  9. [技巧篇]19.InputStream与String,Byte之间互转[转载]

    import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOExceptio ...

  10. springboot以jar包方式启动、关闭、重启脚本

    springboot以jar包方式启动.关闭.重启脚本 启动 编写启动脚本startup.sh #!/bin/bash echo Starting application nohup java -ja ...