69. x的平方根(Python)

更多题目移步【力扣简单题】

题目

难度:★★☆☆☆
类型:数组

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例

示例 1:

输入: 4
输出: 2
示例 2:

输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。

解答

方案1:二分法

这道题目由于只要求取开平方后的整数部分,因此搜索范围有限,可以考虑使用二分法。

  1. 构造数组从0到输入x,该数组中每个元素与其所在位置相等,定义两个指针,左指针left和右指针right,初始位置分别位于数组两端;

  2. 执行循环,循环的控制条件是左指针不能跑到右指针的右边去,每轮循环获得中点所在位置,查看该数的平方s与输入x之间的大小关系:
    (1)s == x:相当于找到了开方结果,直接返回这个数;
    (2)s > x:平方结果较大,删除数组右半部分
    (3)s < x:平方结果较小,删除数组左半部分

  3. 跳出循环时,返回右指针所在位置。

为何是右指针?如果一个数字x开平方x_quare不是整数,那么要跳出循环的前一个状态一定是left=right或者left+1=right,不过无论如何left的位置都是n的向上取整,那么最后一个循环内部所执行的操作就必定是右指针左移到左指针左边,也就是n的向下取整。

class Solution:
    def mySqrt(self, x):
        # 首先,我们构造一个数组,数组中的每个值即为其所在位置(下标),数组范围是从0到x
        left, right = 0, x                          # 初始化左指针和右指针为数组两端数字

        while left <= right:                        # 要求左指针不大于又指针,当满足条件时执行
            # 求取中点位置(位置即为该位置的数),如果数组长度为偶数,取中间偏左的一个
            mid = left + (right - left) // 2

            if mid ** 2 > x:                        # 如果中点的平方大于输入x
                right = mid - 1                     # 抛弃数组右半部分
            elif mid ** 2 < x:                      # 如果中点的平方小于输入x
                left = mid + 1                      # 抛弃数组左半部分
            else:                                   # 如果中点的平方即为输入x
                return mid                          # 直接返回中点即可

        return right                                # 返回结果

方案2:牛顿法

假设我们要求b的平方根\sqrt{b}=x_{0},相当于求x^{2}=b的解,或者说,是函数f\left ( x \right )=x^{2}-b与x轴的交点坐标,我们使用牛顿法计算估算这个坐标。

如图所示是牛顿法的流程示意图,假设我们要计算b=10的平方根,构造函数f\left ( x \right )=x^{2}-10,求该函数与x轴交点的横坐标,我们首先寻找在曲线上的一个点,点的横坐标为10,做这个点的切线,该切线与x轴有一个交点,然后过该点做垂线,与曲线又有一个交点,再次沿着该点做切线,重复上述流程,很显然,随着迭代的进行,垂线与曲线的交点(即下一轮的切点)会不断逼近曲线与x轴的交点,当垂线与曲线的交点的纵坐标小于一定阈值时,我们将这个切点的横坐标近似认为是曲线与x轴交点的横坐标。

牛顿法求取平方根

我们的工作就是每次寻找下一轮切点的坐标。假设当前切点的坐标为\left ( x_{c}, y_{c} \right ),根据抛物线导数公式可得,该切点出切线的斜率为2 x_{c},设切线与x轴交点为\left ( x_{n}, 0 \right ),那么根据直线的斜率定义,可以得到:
\frac{y_{c}-0}{x_{c}-x_{n}}=2x_{c}
解得:
x_{n}=x_{c}-\frac{y_{c}}{2x_{c}}
那么过该交点作垂线后与曲线的交点纵坐标为:
y_{n}=f\left ( x_{n} \right )=x_{n}^{2}-b
下一个切点的坐标即为\left(x_{n}, y_{n} \right)

不断比较当前切点纵坐标与零之间的差值,当小于某一阈值时,结束循环。

class Solution:
    def mySqrt(self, x):

        b = x                               # 改写一下,显得更清楚
        x_c, y_c = b, b * b - b             # 初始化切点坐标
        while abs(y_c) > 1e-4:              # 满足阈值条件
            x_n = x_c - y_c / (2 * x_c)     # 计算下一个切点横坐标,推导公式见上文
            y_n = x_n * x_n - b             # 计算下一个切点纵坐标,推导公式见上文
            x_c, y_c = x_n, y_n             # 更新当前坐标

        return int(x_c)                     # 取出结果的整数部分即可

如有疑问或建议,欢迎评论区留言~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348