持续创作,加速成长!这是我参与「掘金日新计划 · 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
条件判断:
扫描二维码关注公众号,回复:
14208739 查看本文章

- 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才是正确的哦
复制代码
这一题,用以前学过的牛顿迭代法也可以计算,但我摆烂不想写了。
四、编码实现
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;
}
};
复制代码