LeetCode 69.x的平方根题目链接:

​https://leetcode-cn.com/problems/sqrtx/​


题目描述:

实现 int sqrt(int x) 函数。

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

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


示例 1:

输入: 4

输出: 2


示例 2:

输入: 8

输出: 2

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


题目分析:

一眼看到这道题,第一种方法,我们肯定会想到直接调用数学函数求解,笔试面试这样写想必你已经凉凉了。

第二种方法,我们也可以使用暴力破解法求解,首先,如果x为0或1,则它们的非负平方根是它们本身。我们可以大致取中点值,从1到中点值进行遍历,如果当前数平方小于等于x且下一位数平方大于x,则当前数为平方根,但暴力解法耗时长。

第三种方法,二分查找,首先定义左右边界,左边界为0,右边界为x,当左边界小于等于右边界执行循环,求出这段区间的中点值,用中点值的平方与x进行比较,如果中点值平方大于x,则说明答案应该在左子区间,我们对区间范围进行缩小,更新右边界为中点值左边元素。如果中点值平方小于x,则说明答案应该在右子区间,我们对区间范围进行缩小,更新左边界为中点右边元素。如果中点值平方刚好等于x,在说明中点值就是我们要求的答案。如果在循环遍历过程中,左边界大于右边界且左边界平方大于x而右边界平方小于x,即右边界值比左边界值小,返回右边界值即可。

第四种方法,牛顿迭代法,我们可以把这道题转化为函数求解问题。依题意,我们可以将求解平方根转换为求解函数f(y) =y2 - x = 0的解。根据牛顿迭代法公式 xn+1= xn− f(xn) / f′(xn)。因为 f(y) = y2− x = 0,我们把函数代入迭代公式得到 yn+1 = (yn + (x / yn)) / 2,再按牛顿迭代法求解即可。


题解一(笔试面试必挂解):

执行用时: 1 ms

内存消耗: 35.2 MB

class Solution {
public int mySqrt(int x) {
// 笔试面试必挂解法,直接调用库函数
return (int) Math.sqrt(x);
}
}


题解二(暴力解法):

执行用时: 52 ms

内存消耗: 35.2 MB

class Solution {
public int mySqrt(int x) {
// 0的平方根为0,1的非负平方根为1
if (x == 0 || x == 1)
return x;
// 取中点值
long mid = x / 2;
// 从1开始遍历
for (long i = 1; i <= mid; ++i) {
// 如果当前数平方小于等于x且下一位数平方大于x
if (i * i <= x && (i + 1) * (i + 1) > x)
// 则当前数为平方根
return (int)i;
}
// 方法一定要返回一个int值
return -1;
}
}


题解三(二分查找法):

执行用时: 2 ms

内存消耗: 35.5 MB

class Solution {
public int mySqrt(int x) {
// 定义左右边界
long left = 0, right = x;
// 当左边界小于等于右边界执行循环
while(left <= right) {
// 定义中点
long mid = (left + right) / 2;
// 中点值平方大于x,缩小范围至左区间
if(mid * mid > x)
// 右边界更新为中点的左边元素
right = mid - 1;
// 中点值平方小于x,缩小范围至右区间
else if(mid * mid < x)
// 左边界更新为中点的右边元素
left = mid + 1;
// 中点值平方等于x,即mid为x的平方根
else if(mid * mid == x)
// 返回平方根整数部分
return (int) mid;
}
// 如果左边界平方大于x而右边界平方小于x,即右边界值符合条件
if(left * left > x && right * right < x)
// 返回右边界值
return (int) right;
return -1;
}
}


题解四(牛顿迭代法):

执行用时: 2 ms

内存消耗: 35.5 MB

class Solution {
public int mySqrt(int x) {
long a = x;
while (a * a > x)
a = (a + x / a) / 2;
return (int) a;
}
}


题目来源:力扣(LeetCode)