【人工智能面试算法题】求解一元二次方程极值点、求100!中0的个数、求sqrt(x)

目录

1.求解一元二次方程极值点

2.求sqrt(x)

3.求100!末尾0的个数


#刷题记录#

人工智能算法岗面试时,简单算法题必不可少,今天来总结三道常见试题,一起来学习~

1.求解一元二次方程极值点

2.求sqrt(x)

对应力扣:LCR 072. x 的平方根 - 力扣(LeetCode)

3.求100!末尾0的个数

对应力扣:172. 阶乘后的零 - 力扣(LeetCode)

1.求解一元二次方程极值点

题目:解决方程:x^2 - 4x + 4 = 0

思路:

这道题其实是考察我们对梯度下降,学习率设置等基础的掌握。

我们的思路可以是通过迭代的方式,逐步调整参数,以达到最小化或最大化某个函数(比如损失函数)的目标。

  • 首先我们求出方程的导数,对于上面方程的导数是2x-4
  • 然后根据初始值start求的当前梯度,然后开始循环,根据梯度pre_gred和学习率learn_rate更新x的值,再计算更新后的梯度。
  • 循环结束的条件是相邻两次梯度乘积为负,然后返回x

代码如下:

def gradient_descent(start,learn_rate):

    x = start
    pre_grad = 2 * start - 4
    while True:
        next_x = x - learn_rate*pre_grad
        cur_grad = 2 * next_x - 4
        if pre_grad * cur_grad <= 0:
            break
        x = next_x

    return x

x_soultion = gradient_descent(0,0.0001)
print(x_soultion)

结果:

1.999999999999845

2.求sqrt(x)

解法一:首先我们会想到二分法,思路如下:

  • 设定初始值r = x
  • 设置迭代,迭代停止条件是abs(r*r-x) < tolerance
  • 中间过程:令left = 1,right = x,mid = ((left+right)/2)如果mid^2大于x,则mid = right,否则mid = left
  • 最后返回mid

代码如下:

def binary_search_sqrt(x, tolerance=1e-10):
    """
    使用二分查找法计算平方根
    x: 要计算平方根的数
    tolerance: 容忍误差,迭代停止的条件
    """
    left, right = 1, x
    if x < 1:  # 如果x小于1,那么平方根在x和1之间
        left, right = x, 1
    while right - left > tolerance:
        mid = (left + right) / 2
        if mid * mid > x:
            right = mid
        else:
            left = mid
    return (left + right) / 2  # 当区间足够小,返回区间中点作为近似值

# 示例:计算4的平方根
print(binary_search_sqrt(4))

解法二:下面我们尝试用以一种更优雅的解法,牛顿迭代法!

牛顿迭代法,也称为牛顿-拉弗森方法(Newton-Raphson method),是一种在实数域和复数域上迭代求解方程的根的方法。求解\sqrt{x}实际上是在求解方程f(y) = y^2 - x = 0的正根。

牛顿迭代法的基本原理是使用函数的泰勒级数的前几项来寻找方程的根。对于方程 f(y) = 0,从一个初始估计y_{0}开始,可以通过一下迭代公式逼近方程的根:y_{n+1} = y_{n} - \tfrac{f(y_{n})}{f^{'}(y_{n})}在这里,f^{'}(y_{n})是函数f(y)y_{n}处的导数。

对于\sqrt{x},我们可以将f(y)设置为y^2 - x,这样f^{'}(y_{})就是2y。迭代公式变为:y_{n+1} = y_{n} - \frac{y_{n}^{2}-x}{2y_{n}} = \frac{y_{n}}{2} + \frac{x}{2y_{n}}.

这种方法每次迭代都会使得y_{n}更加接近方程的根,即\sqrt{x}。牛顿迭代法的优点就是收敛速度快,特别是当初始值选择得较好时。

代码如下:

def newton_sqrt(x, tolerance=1e-10):
    """
    使用牛顿迭代法计算平方根
    x: 要计算平方根的数
    tolerance: 容忍误差,迭代停止的条件
    """
    y = x  # 初始估计值
    while True:
        y_next = 0.5 * (y + x / y)
        if abs(y - y_next) < tolerance:  # 当前后两次迭代结果足够接近时停止迭代
            break
        y = y_next
    return y

# 示例:计算4的平方根
print(newton_sqrt(4))

运行结果:

1.999999999985448

3.求100!末尾0的个数

这道题上来一看可能的想法是,直接计算出来然后取余计算。我们来看看它计算出来的长度:

n = 100
mul = 1
while n!=0:
    mul *=n
    n = n-1
print(mul)

===============
输出:(933262154439441526816992388562667004907159682/
      6438162146859296389521759999322991560894/
      1463976156518286253697920827223758251185210916864000000000000000000000000)

可以看到输出是非常长的,所消耗的算力也是非常之大,那有没有更加简便的方法?

我们可以换个思路:在100!中末尾所有的0都是由2*5得到的,这里的2和5是指所有数字的因数。 

很显然,在这些数字的所有因子中,2一定比5多。所以我们求出1-100这100个数的所有因子中5的个数有多少。

首先,我们需要了解的一点是:对于100//5 = 20来说,一方面代表100除以5的商,另一方面,还代表了1-100中能够被5整除的数的个数。这里可能需要多推敲一下。

然而,像10,15,20等这些数字提供了一个5,对于25,50,75,100这些提供了两个5。如果是125,则提供了3个5。

代码如下:

def count_zeros_in_factorial(n):
    count = 0
    i = 5
    while n // i != 0:
        count += n // i
        i *= 5
    return count

print(count_zeros_in_factorial(100))

以上

学习在于总结和坚持,共勉

最近更新

  1. TCP协议是安全的吗?

    2024-01-31 11:44:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-31 11:44:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-31 11:44:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-31 11:44:01       18 阅读

热门阅读

  1. Spring-yml

    2024-01-31 11:44:01       29 阅读
  2. C# 策略模式(Strategy)

    2024-01-31 11:44:01       29 阅读
  3. Threejs API——`OrbitControls`相机控件

    2024-01-31 11:44:01       32 阅读
  4. Nginx中日志模块的应用和配置!

    2024-01-31 11:44:01       32 阅读