Sqrt(x)——二分法,防越界
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 - (xi2 - 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)——二分法,防越界的更多相关文章
- saturate_cast防越界函数
CV_IMAGE_ELEM(img2,uchar,i,j*3+c)=saturate_cast<uchar>(alpha*( CV_IMAGE_ELEM(img,uchar,i,j*3+c ...
- 【经典面试题】实现平方根函数sqrt
本文将从一道经典的面试题说起:实现平方根函数,不得调用其它库函数. 函数原型声明例如以下: double Sqrt(double A); 二分法 二分法的概念 求,等价于求方程的非负根(解).求解方程 ...
- 开博第一篇:DHT 爬虫的学习记录
经过一段时间的研究和学习,大致了解了DHT网络的一些信息,大部分还是参会别人的相关代码,一方面主要对DHT爬虫原理感兴趣,最主要的是为了学习python,大部分是别人的东西原理还是引用别人的吧 DHT ...
- CODEVS 2055 集合划分
[题目描述] 对于从1到N(1<=N<=39)的连续整数集合,划分成两个子集合,使得每个集合的数字之和相等. 举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,他们每个的所有数字 ...
- C++Primer第5版学习笔记(一)
C++Primer第5版学习笔记(一) 第一.二章的重难点内容 这个笔记本主要记录了我在学习C++Primer(第5版,中文版)的过程中遇到的重难点及其分析.因为第一.二章都比较简单,因 ...
- 快速排序 partition函数的所有版本比较
partition函数是快排的核心部分 它的目的就是将数组划分为<=pivot和>pivot两部分,或者是<pivot和>=pivot 其实现方法大体有两种,单向扫描版本和双向 ...
- FJUT寒假作业涨姿势题解
题意非常简单易懂,对于涨姿势0,数据非常小,比较容易想到的是直接循环暴力解题完成任务.把数据放入数组arr,循环i,j控制所有区间算和.结果记入vis. 到了涨姿势1,2,3,我们观察数据变化,发现数 ...
- 洛谷P2569 股票交易
题目传送门https://www.luogu.org/problemnew/show/P2569 第一眼看题就觉得是个dp ,然后看到2000的范围,hmm大概是个n^2的2维dp 开始设状态,第一维 ...
- P1282 多米诺骨牌
P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S ...
随机推荐
- call和apply第一个参数为null/undefined,函数this指向全局对象
call和apply第一个参数为null/undefined,函数this指向全局对象,在浏览器中是window,在node中是global 在严格模式中(ie 6/7/8/9 除外),传入null/ ...
- 【神仙DP】【单调队列】【模拟题】区间覆盖
传送门 Description 给出数轴上的n个线段,保留最多k条线段,问这些被保留下来的线段的并集长度为最多为多少. Input 第一行两个数n和k 接下来n行,每行两个数,表示一条线段的左右端点. ...
- getopt和getopt_long参数处理
1:getopt函数 getopt主要用于解析程序运行时所带的参数,原型如下: #include <unistd.h> int getopt(int argc, char * const ...
- JQuery学习二(获取元素控件并控制)
$(’#id‘).+function; 例如: 1 <head> 2 <title>JQuery</title> 3 <script src="js ...
- HDU2732 最大流
Leapin' Lizards Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- [解决] Error Code: 1044. Access denied for user 'root'@'%' to database
今天在测试集群用的mysql上,遇到个权限的问题: SQLException : SQL state: 42000 com.mysql.jdbc.exceptions.jdbc4.MySQLSynta ...
- CentOS 下安装 LEMP 服务(nginx、MariaDB/MySQL 和 php)
转载自:https://linux.cn/article-4314-1.html 编译自:http://xmodulo.com/install-lemp-stack-centos.html 作者: D ...
- LightOJ 1306 - Solutions to an Equation 裸EXGCD
本题是极其裸的EXGCD AX+BY+C=0 给你a b c 和x与y的区间范围,问你整数解有几组 作为EXGCD入门,题目比较简单 主要需要考虑区间范围的向上.向下取整,及正负符号的问题 问题是这正 ...
- 元类编程-- metaclass
#类也是对象,type创建类的类 def create_class(name): if name == "user": class User: def __str__(self): ...
- bzoj 2276: [Poi2011]Temperature——单调队列
Description 某国进行了连续n天的温度测量,测量存在误差,测量结果是第i天温度在[l_i,r_i]范围内. 求最长的连续的一段,满足该段内可能温度不降 第一行n 下面n行,每行l_i,r_i ...