算法题:求正实数x的平方根 (注意不是整数)& 求方程的根
算法题:求正实数x的平方根
不同于LC69,面试题要求x是正实数,而不是整数。并且需要注意x可能是小数,此时x的平方根是大于x的。
二分法
https://blog.csdn.net/weixin_27625589/article/details/116221090
copydef mySqrt2(x): # 正实数x的平方根,注意是实数、注意可能是正的小数
left = 0
right = max(x, 1.0) # x是正小数的情况下,平方根比x大,但肯定是小于1.0的
while left < right:
mid = (left + right) / 2.0 # 实数
# print(left, right, mid, mid * mid)
if abs(mid * mid - x) < 1e-6: # 精度
return mid
if mid * mid > x:
right = mid # 实数,不是mid-1
elif mid * mid < x:
left = mid
print(mySqrt2(10), mySqrt2(0.09))
# 3.162277638912201 0.2999992370605469
梯度下降法
https://leetcode-cn.com/problems/sqrtx/solution/bu-chong-yi-ge-ti-du-xia-jiang-fa-by-tra-fkds/
!
copyimport math
class Solution:
# 请注意,此处的参数原题是 x,
# 为了更好理解改为了 t, 而 x 用于迭代过程,和公式相匹配
def mySqrt(self, t: int) -> int:
# 初始值,注意,初始值不能设为0,否则所有迭代结果均为0
x = 1
# 定义学习率
learning_rate = 0.00001
# 定义精度
eps = 1e-5
while math.fabs(x ** 2 - t) > eps:
# 梯度下降迭代过程
x = x - learning_rate * self.gradient(x, t)
# res = int(x)
# # 注意边界值,因为 int 会向下取整,所以需判断 int+1 是否更接近答案
# return (res + 1) if (res+1)**2 <= t else res
return x # 返回实数,不要取整
def gradient(self, x, t):
return 4 * x * (x ** 2 - t)
s = Solution()
print(s.mySqrt(0.09))
# 0.30001666619774
假如现在要求的是根号2 即 的解 使用梯度下降法,梯度下降主要通过求梯度为0的点,得到凸函数的全局最小值 是凸函数。首先构建损失函数为凸函数的目标函数, 使得目标函数的最小值对应的是我们要求的值
:逼近t的损失函数是 , 对x求梯度是:
copydef gradient_descent(n):
x = float(random.randint(1, 100))
array = [] # 保存每一步的估计
while (abs(x ** 2 - n) > 0.0001): # 精度是0.0001, 也可以使用梯度绝对值不接近0作为继续循环的条件
x = x - 0.00001 * 4 * x * (x ** 2 - n) # 学习率是0.00001,
array.append(x)
return array
n=10
array = gradient_descent(n)
# x = range(len(array))
# plt.plot(x, array, color='b')
# plt.show()
import math
print(math.sqrt(n), array[-1])
牛顿法
https://blog.csdn.net/dpengwang/article/details/99092278
https://blog.csdn.net/songyunli1111/article/details/90474836
copyimport random
import matplotlib.pyplot as plt
import math
def Newton(n): # target
array = [] # 保存每一步估计
x = float(random.randint(1, 100)) # 随机初始点
while(abs(x**2 - n) > 0.000000001): # 精度, 也可以使用梯度绝对值不接近0作为继续循环的条件
x = x - (x**2 - n ) / (2*x) # 牛顿法公式
array.append(x)
return array
n=10
array = Newton(n)
# x = range(len(array))
# plt.plot(x, array, color='b')
# plt.show()
print(math.sqrt(n), array[-1])
补充:数值计算方法:二分法求解方程的根
https://blog.csdn.net/weixin_27625589/article/details/116221090
copydef fun(x):
return x ** 2 + x - 6
def newton(a,b,e): # e 是 精度
x = (a + b)/2.0
if abs(b-a) < e:
return x
else:
if fun(a) * fun(x) < 0:
return newton(a, x, e)
else:
return newton(x, b, e)
print(newton(-5, 0, 5e-5))
print(newton(0, 5, 5e-5))
# -3.000011444091797
# 1.9999885559082031
copy# 二分法求解方程的根
def fun(x):
return x ** 2 + x - 6
def binSearch(a, b): # 当 fun(a), fun(b)异号,且设只有一个根的时候
left, right = a, b
while left <= right:
mid = (left + right) / 2.0
if abs(fun(mid)) < 1e-6:
return mid
if fun(mid) * fun(left) < 0: # left和mid的函数值异号
right = mid
else:
left = mid
print(binSearch(-5, 0), "\n", binSearch(0, 5))
# -3.0000001192092896
# 1.9999998807907104
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步