本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
一、题目描述
二、解题思路
题目很简单,数学方法我们在这里就不赘述了。
我想要说的是这题的二分查找边界的确定。
那我们开始分析吧,这题是怎么考虑到使用二分的呢?
1.枚举
求x的平方根的整数部分,那明显的我们可以通过枚举从1开始一个一个算。当k^2>x时k-1就是我们要的答案。
时间复杂度分析
- O(n)
空间复杂度分析
- O(1)
2.二分查找
由于x 平方根的整数部分ans 是满足 k^2≤x 的最大k值,因此我们可以对k进行二分查找,从而得到答案。 二分查找的下界为0,上界可以粗略地设定为x。在二分查找的每一步中,我们只需要比较中间元素 mid 的平方与 x 的大小关系,并通过比较的结果调整上下界的范围。但是其中的边界需要特别注意下(看代码注释)。
时间复杂度分析
- O(logn)
空间复杂度分析
- O(1)
三、代码实现
二分需要注意的是每次循环一定要缩减范围,不然就会死循环。
class Solution {
public int mySqrt(int x) {
//为啥不能从1开始?leetcode测试用例有输入0
int l = 0, r = x;
//分析下输入1的情况
while(l<=r){
int middle = (l+r)/2;
if((long)middle*middle<=x){
//因为要用l作为答案,这里需要提前退出循环
if((long)(middle+1)*(middle+1)>x){
l=middle;
break;
}
//缩减范围
l = middle+1;
}else{
//缩减范围
r = middle-1;
}
}
return l;
}
}
不晓得我讲清楚了没有,请大家多多指教。
今日打卡结束!