引言
随着AI领域的发展,底层算法确实起到了决定性的作用。为了跟上这个快速发展的领域,我们需要不断学习和提升自己的技能。刷题是一种很好的方式,可以帮助我们巩固基础知识,提高解决问题的能力。
介绍
豆包青训营是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目。该项目的目标是培养具有职业竞争力的优秀开发工程师,并提供全程免费的课程,不收取任何费用。
课程内容和方向
豆包青训营的课程涵盖前端、后端和AI方向。在这个飞速发展的AI时代,学员将与豆包MarsCode团队一起深入探索技术领域,学习和运用AI,提高编程效率。此外,课程还包括大数据方向,适合对大数据感兴趣的学员学习,
本文提供训练营试题解析供参考
试题1:小R的字符串生成方式
问题描述:
小R有一个初始为空的字符串 s,她的目标是生成一个给定的字符串 t。她可以使用以下两种操作来生成这个字符串:
1.将任意一个字母添加到 s 的末尾。
2.选择 s 中一个长度不小于 2 的后缀,并将其复制添加到 s 的末尾。
小R想知道,有多少种不同的方法可以从空串 s 生成字符串 t。由于结果可能非常大,请对 10^9 + 7 取模。
def solution(t: str) -> int:
MOD = 10**9 + 7
n = len(t)
# 初始化 dp 数组
dp = [0] * (n + 1)
dp[0] = 1 # 生成空字符串的方法数为 1
# 填充 dp 数组
for i in range(1, n + 1):
# 通过添加一个字符来生成 t[i-1]
dp[i] = dp[i - 1]
# 通过复制后缀来生成 t[i-1]
for j in range(1, i):
if t[i - j:i] == t[i - 2 * j:i - j]:
dp[i] = (dp[i] + dp[i - j]) % MOD
return dp[n]
if __name__ == '__main__':
print(solution("ababa") == 3)
print(solution("abcabc") == 2)
print(solution("aaaa") == 10)
试题2:小U的相似字符串
问题描述:
小U认为两个字符串相似,当且仅当它们每个字母的个数都相等。例如,“abcbd” 和 “dbcba” 是相似的,“abcd” 和 “abcd” 也是相似的;而 “abb” 和 “aab” 不相似,“ac” 和 “cca” 也不相似。
现在小U手中有 n 个字符串,她想知道有多少对字符串是相似的。
def solution(n: int, strings: list) -> int:
from collections import Counter
# 用于存储每个字符串的统计结果
count_dict = {}
# 遍历每个字符串
for s in strings:
# 统计字符串中每个字母的个数
count = Counter(s)
# 将统计结果转换为一个可以比较的键
key = tuple(sorted(count.items()))
# 将键存储在字典中,并记录出现的次数
if key in count_dict:
count_dict[key] += 1
else:
count_dict[key] = 1
# 计算相似字符串的对数
result = 0
for key in count_dict:
# 如果某个键出现了 k 次,那么可以组成 k*(k-1)/2 对相似字符串
k = count_dict[key]
result += k * (k - 1) // 2
return result
if __name__ == '__main__':
print(solution(7, ["abcbd", "dbcba", "abcd", "abcd", "adbc", "aa", "aa"]) == 5)
print(solution(3, ["aab", "bba", "baa"]) == 1)
print(solution(5, ["abc", "def", "ghi", "jkl", "mno"]) == 0)
试题3:序列的第k小数问题
问题描述:
给定一个长度为 n 的整数序列 a,你需要找到所有满足以下条件的整数对 (l, r):
1.区间 [l, r] 的长度不小于 k,即 r - l + 1 ≥ k。
2.区间 [a_l, a_{l+1}, …, a_r] 中的第 k 小的数等于 x。
你的任务是计算所有满足条件的 (l, r) 对的数量。
def solution(n: int, x: int, k: int, a: list) -> int:
count = 0 # 初始化计数器
# 遍历所有可能的区间 [l, r]
for l in range(n):
for r in range(l, n):
if r - l + 1 >= k: # 检查区间长度是否不小于 k
# 获取当前区间 [l, r] 的子数组
subarray = a[l:r+1]
# 检查第 k 小的数是否等于 x
# 这里可以使用排序或优先队列来实现
# 例如:sorted(subarray)[k-1] == x
if sorted(subarray)[k-1] == x:
count += 1
return count
if __name__ == '__main__':
print(solution(n = 5, x = 3, k = 2, a = [1, 2, 3, 4, 5]) == 3)
print(solution(n = 6, x = 2, k = 4, a = [4, 1, 5, 2, 4, 6]) == 0)
print(solution(n = 7, x = 3, k = 5, a = [3, 5, 2, 7, 5, 6, 5]) == 0)
试题4:拨号器
问题描述:
def solution(n: int) -> int:
MOD = 10**9 + 7
# 定义骑士可以跳跃的规则
jumps = {
1: [6, 8],
2: [7, 9],
3: [4, 8],
4: [3, 9, 0],
5: [], # 5没有跳跃目标
6: [1, 7, 0],
7: [2, 6],
8: [1, 3],
9: [2, 4],
0: [4, 6]
}
# 初始化dp数组
dp = [[0] * 10 for _ in range(n)]
# 初始状态:当n=1时,每个数字都可以作为起点
for i in range(10):
dp[0][i] = 1
# 状态转移
for i in range(1, n):
for j in range(10):
for k in jumps[j]:
dp[i][j] = (dp[i][j] + dp[i-1][k]) % MOD
# 计算最终结果
result = sum(dp[n-1]) % MOD
return result
if __name__ == '__main__':
print(solution(1) == 10)
print(solution(2) == 20)
print(solution(3) == 46)
print(solution(4) == 104)
试题5:最大区间乘积问题
问题描述:
小R正在处理一个数组序列,他的任务是找出一个区间,使得这个区间的所有数经过以下计算得到的值是最大的:
区间中的最小数 * 区间所有数的和
小R想知道,经过计算后,哪个区间能产生最大的值。你的任务是帮助小R编写一个程序,输出最大计算值。
例如:给定数组序列 [6, 2, 1],可以得到以下区间及其计算值:
[6] = 6 * 6 = 36
[2] = 2 * 2 = 4
[1] = 1 * 1 = 1
[6, 2] = 2 * 8 = 16
[2, 1] = 1 * 3 = 3
[6, 2, 1] = 1 * 9 = 9
根据这些计算,小R可以选定区间 [6],因此输出的最大值为 36。
def solution(n: int, a: list) -> int:
# 初始化最大值
max_value = 0
# 遍历数组中的每个元素
for i in range(n):
# 找到以当前元素为最小值的最大区间
left = i
right = i
# 向左扩展,找到左边界
while left > 0 and a[left - 1] >= a[i]:
left -= 1
# 向右扩展,找到右边界
while right < n - 1 and a[right + 1] >= a[i]:
right += 1
# 计算当前区间的和
current_sum = sum(a[left:right + 1])
# 计算当前区间的值
current_value = a[i] * current_sum
# 更新最大值
max_value = max(max_value, current_value)
return max_value
if __name__ == '__main__':
print(solution(n = 3, a = [6, 2, 1]) == 36)
print(solution(n = 4, a = [5, 1, 4, 3]) == 25)
print(solution(n = 5, a = [7, 3, 2, 1, 8]) == 64)