前言
本篇文章为大家提供 LeetCode 69. x的平方根 的题解
一、题目描述与分析
题目链接:Leetcode 69.x 的平方根
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
题目分析:
这道题目是一个经典的问题,就是不通过内置函数来实现求平方根的操作。
二、题解以及代码
1、牛顿迭代法
牛顿迭代法的基本思想是通过选择一个初始猜测值(初始估计),然后使用切线来逼近方程f(x) = 0
的根。切线的斜率由f(x)
在当前猜测值处的导数(即f'(x)
)给出。通过计算切线与x轴的交点,可以获得一个新的近似根,然后将该点作为下一轮迭代的新猜测值。这个过程会不断重复,直到找到足够接近实际根的近似值。
这里我们需要求出 x
的平方根,就可以假想一个函数f(x) = x^2 - c
,当这里的 c
是我们的常数项的时候,这里的 x
就是我们需要求的 c
的根。
时间复杂度:O(log N)
空间复杂度:O(1)
int mySqrt(int x) {
if (x == 0) return 0; // 特殊情况:x为0时直接返回0
double prev = 0; // 前一次的近似值
double current = 1; // 当前的近似值
while (prev != current) {
prev = current;
current = 0.5 * (current + x / current); // 牛顿迭代公式
}
return (int)current;
}
2、二分法
通过经典的二分查找的思想来解决这个问题,需要注意的点就是判断条件和替换 l
和 r
的时候应该用什么来替换。
int mySqrt(int x) {
if (x == 0) return 0; // 特殊情况:x为0时直接返回0
// 使用二分查找法来寻找平方根
long left = 1; // 左边界
long right = x; // 右边界
while (left <= right) {
long mid = left + (right - left) / 2;
long square = mid * mid;
if (square == x) {
return (int)mid;
} else if (square < x) {
left = mid + 1;
} else {
right = mid - 1;
}
}
// 返回右边界,它是小于等于平方根的最大整数
return (int)right;
}
时间复杂度:O(log N)
空间复杂度:O(1)
3、袖珍计算器
通过将开平方根的操作转化为指数和对数运算来简化代码的时间复杂度,需要注意的是返回时应该返回 ans
还是 ans + 1
。
int mySqrt(int x) {
if (x == 0) return 0; // 特殊情况:x为0时直接返回0
double result = exp(0.5 * log(x));
long ans = (long)result; // 使用long类型来存储整数部分
if ((ans + 1) * (ans + 1) <= x) {
return (int)(ans + 1);
}
return (int)ans;
}
时间复杂度:O(1)
空间复杂度:O(1)
总结
我为大家提供了3种不同的方法来解决这个问题,分别是二分法、牛顿迭代法、袖珍计算器法,这三种方法各有优劣,大家可以选择自己喜欢的方法来解决这道题目。
那么今天的文章就到此为止了,希望我的思路和解决代码可以帮助到大家,大家有什么问题可以在评论区提出来,博主看到之后都会回复,也可以给博主发私信,欢迎大家与博主一同交流进步。