算法题每日一练---第102天:x 的平方根

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

一、问题描述

给你一个非负整数x ,计算并返回 x 的 算术平方根

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

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

题目链接:扑克牌中的顺子

二、题目要求

样例 1

输入: x = 4
输出: 2
复制代码

样例 2

输入: x=28
输出: 5
复制代码

考察

1.二分、牛顿迭代法
2.建议用时10~25min
复制代码

三、问题分析

这一题感觉出的还比较巧妙,首先要注意题目中的要求,不可以直接使用置指数函数和算符,不然这题一行代码就解决了。

很明显,不让用函数,我们可以使用二分法一步步逼近结果,得出最接近结果的值,首先二分法的初始化步骤

左指针 l:初始值指向1

右指针 r:初始值指向r

中间值 mid:为 l+(r-l)/2

条件判断:

  • mid*mid==x 直接返回mid
  • mid*mid>x r=mid-1
  • mid*mid<x l=mid+1

注意这里有优化的部分,mid的范围32位,mid*mid就会变成64位,需要long 存储内容才行。这里我们可以把乘法改成除法,优化一下代码,结果会更加准确。

  • mid==x/mid 直接返回mid
  • x/mid<mid r=mid-1
  • x/mid>mid l=mid+1

注意,循环之外的返回值是r不是mid,这是为什么呢?

我详细讲解一下:28 5的运算过程

l      mid        r
1       7         14      7*7>28    r=7-1=6
1       3          6      3*3<28    l=3+1=4
4       5          6      5*5<28    l=5+1=6  
6       6          6      6*6>28    r=6-1=5  返回r才是正确的哦
复制代码

这一题,用以前学过的牛顿迭代法也可以计算,但我摆烂不想写了。

25.gif

四、编码实现

class Solution {
public:
    int mySqrt(int x) {
        if(x==0||x==1)
            return x;
        int l=1,r=x/2,mid;
        while(l<=r)
        {
            mid=l+(r-l)/2;
            if(mid==x/mid)  return mid;
            else if(x/mid<mid) r=mid-1;
            else if(x/mid>mid) l=mid+1;
        }
        return r;
    }
};
复制代码

五、测试结果

1.png

2.png

19.png

猜你喜欢

转载自juejin.im/post/7102412921539395615