题目

分析 & 代码
第一想法是从1开始一个一个去试,这种想法比较naive,所以比较慢
需要注意的就是base开成long long的类型,不然会产生溢出
class Solution {
public:
int mySqrt(int x) {
if (x == 0) return 0;
long long base = 1;
for (; base * base <= x; ++base) {
if ((base + 1) * (base + 1) > x)
break;
}
return base;
}
};
跑了16ms 并不是最好的做法
换种思路,一个数n,它的方根只可能在1到n之间的某个数,而这些数是有序的,所以很容易联想到二分。
从1到n的范围,进行二分。具体的二分逻辑不难推出来,需要注意的就是最后return的值应该是右边界,原因在于跳出循环的时候,l是大于r的,而这里求的根是需要做向下取整的,所以应该是r而不是l
代码如下:
class Solution {
public:
int mySqrt(int x) {
if (x == 0) return 0;
int l = 1, r = x, mid;
while (l <= r) {
// 避免溢出
mid = l + (r - l) / 2;
// 除法避免溢出
if (x / mid > mid) l = mid + 1;
else if(x / mid == mid) return mid;
else r = mid - 1;
}
return r;
}
};
这次就只跑了0ms,比之前的方法提高不少
该博客主要介绍了LeetCode第69题的解决方案,通过分析题目并尝试了从1开始试的朴素方法,但因效率低下而放弃。博主随后采用二分查找法,详细解释了二分查找的逻辑,指出在确定方根的范围内进行二分,并强调返回值应为右边界,以确保结果向下取整。经过改进后的代码运行时间为0ms,大幅提高了效率。
816

被折叠的 条评论
为什么被折叠?



