算法工程师秋招面试题汇总(2)- 算法篇

1.实现n阶乘

直接用math.factotial(n)了

2.手写,随机颜色

import random

def generate_random_color():
    # 生成随机的 RGB 值
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    
    # 返回 RGB 形式
    return (r, g, b)

def generate_random_color_hex():
    # 生成随机的 RGB 值
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    
    # 转换为十六进制形式并返回
    return f'#{r:02X}{g:02X}{b:02X}'

# 测试
print("随机 RGB 颜色:", generate_random_color())
print("随机十六进制颜色:", generate_random_color_hex())

随机 RGB 颜色: (255, 87, 51)
随机十六进制颜色: #FF5733


3.矩阵求最长路径  

一个M*N矩阵,从左上角开始,只能向右或向下走,求走过路径值的和的最大值

 动态规划(Dynamic Programming)的方法

思路

  1. 定义状态:设 dp[i][j] 表示到达位置 (i,j)(i, j)(i,j) 时的最大路径值和。

  2. 状态转移方程

    • 从左边来:dp[i][j] = dp[i][j-1] + matrix[i][j]
    • 从上边来:dp[i][j] = dp[i-1][j] + matrix[i][j]
    • 综合起来: dp[i][j]=matrix[i][j]+max⁡(dp[i−1][j],dp[i][j−1])dp[i][j] = \text{matrix}[i][j] + \max(dp[i-1][j], dp[i][j-1])dp[i][j]=matrix[i][j]+max(dp[i−1][j],dp[i][j−1])
    • 边界条件:
      • dp[0][0] = matrix[0][0](起点)
      • 第一行:dp[0][j] = dp[0][j-1] + matrix[0][j]
      • 第一列:dp[i][0] = dp[i-1][0] + matrix[i][0]
  3. 最终结果dp[M-1][N-1] 就是从左上角到右下角的最大路径值和。

示例代码

以下是用 Python 实现该算法的示例代码:

def max_path_sum(matrix):
    if not matrix or not matrix[0]:
        return 0

    M = len(matrix)
    N = len(matrix[0])
    
    # 创建一个 dp 矩阵,大小为 M x N
    dp = [[0] * N for _ in range(M)]
    
    # 初始化起点
    dp[0][0] = matrix[0][0]
    
    # 初始化第一行
    for j in range(1, N):
        dp[0][j] = dp[0][j-1] + matrix[0][j]
    
    # 初始化第一列
    for i in range(1, M):
        dp[i][0] = dp[i-1][0] + matrix[i][0]

    # 填充 dp 矩阵
    for i in range(1, M):
        for j in range(1, N):
            dp[i][j] = matrix[i][j] + max(dp[i-1][j], dp[i][j-1])

    # 返回右下角的最大路径和
    return dp[M-1][N-1]

# 测试示例
matrix = [
    [5, 3, 2, 1],
    [1, 2, 10, 1],
    [4, 3, 2, 1],
    [0, 6, 1, 2]
]

result = max_path_sum(matrix)
print("最大路径和:", result)  # 输出: 27
 

4.柱子盛水最大体积,接雨水改编,柱子宽度不一定相等

复杂度分析

  • 时间复杂度:O(M * N),因为我们需要填充整个 dp 矩阵。
  • 空间复杂度:O(M * N),由于我们使用了一个额外的 dp 矩阵。

问题描述

给定一个数组,其中每个元素表示柱子的高度,而每个柱子的宽度可以不相等。求在这些柱子之间可以盛多少水。

解题思路

  1. 使用双指针法:我们可以使用两个指针,分别从数组的两端向中间移动。通过维护左侧和右侧的最大高度来计算当前指针处能够存储的水量。

  2. 算法步骤

    • 初始化两个指针 leftright 分别指向数组的开头和结尾。
    • 初始化 left_maxright_max,分别用来记录当前左侧和右侧的最大柱子高度。
    • 遍历整个数组,更新 left_maxright_max,并根据较小的最大高度来计算当前的水量。
    • 移动指向较小柱子的指针,继续迭代直到两个指针相遇。

def trap(height):
    if not height:
        return 0

    left, right = 0, len(height) - 1
    left_max, right_max = height[left], height[right]
    water_trapped = 0

    while left < right:
        if left_max < right_max:
            left += 1
            left_max = max(left_max, height[left])
            water_trapped += left_max - height[left]
        else:
            right -= 1
            right_max = max(right_max, height[right])
            water_trapped += right_max - height[right]

    return water_trapped

# 测试示例
heights = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]
result = trap(heights)
print("可以盛水的体积:", result)  # 输出: 可以盛水的体积: 6

代码说明

  1. 初始化

    • leftright 指针分别指向数组的开始和结束。
    • left_maxright_max 用于存储当前左侧和右侧的最大高度。
    • water_trapped 用于累计存储的水量。
  2. 双指针遍历

    • 使用 while 循环遍历,条件是 left 指针小于 right 指针。
    • 根据 left_maxright_max 的大小决定移动哪个指针。
    • 更新当前指针处的最大高度,并计算存储的水量。
  3. 返回结果:最后返回计算得到的 water_trapped,即可以盛水的体积。

复杂度分析

  • 时间复杂度:O(n),其中 n 是柱子的数量,因为我们只需遍历一次数组。
  • 空间复杂度:O(1),只使用了常量级别的额外空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值