介绍
豆包青训营是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目。该项目的目标是培养具有职业竞争力的优秀开发工程师,并提供全程免费的课程,不收取任何费用。
课程内容和方向
豆包青训营的课程涵盖前端、后端和AI方向。在这个飞速发展的AI时代,学员将与豆包MarsCode团队一起深入探索技术领域,学习和运用AI,提高编程效率。此外,课程还包括大数据方向,适合对大数据感兴趣的学员学习,
本文提供训练营试题解析供参考
试题1:最短评估时间问题
问题描述:
小R在教室里有N名学生和M名教职员工。每个教职员工的评估速度不同,评估每个学生所需的时间不同。你得到一个数组A,其中A[i]表示第i名教职员工对一名学生进行评估所需的时间(以分钟为单位)。
教职员工需要对所有学生进行评估,每名教职员工在任意时刻只能评估一名学生。评估完成后,教职员工可以立即开始评估下一名学生。你的任务是找到在这些条件下评估所有学生所需的最短总时间。
def solution(N: int, M: int, A: list) -> int:
# 定义一个函数来验证在给定时间 `T` 内是否所有学生都能被评估完毕
def can_evaluate_all_students(T: int) -> bool:
# 计算在时间 `T` 内每个教职员工最多可以评估多少学生
total_students = 0
for time in A:
total_students += T // time
# 如果总数大于等于 `N`,则返回 `True`,否则返回 `False`
return total_students >= N
# 使用二分查找来找到最短时间 `T`
left, right = 1, max(A) * N # 初始化二分查找的左右边界
while left < right:
mid = (left + right) // 2
if can_evaluate_all_students(mid):
right = mid # 如果 `mid` 时间内可以评估所有学生,尝试更短的时间
else:
left = mid + 1 # 如果 `mid` 时间内不能评估所有学生,尝试更长的时间
return left
if __name__ == '__main__':
print(solution(N = 2, M = 2, A = [3, 4]) == 4)
print(solution(N = 3, M = 2, A = [5, 7]) == 10)
print(solution(N = 5, M = 3, A = [2, 3, 5]) == 6)
试题2:查找按位XOR等于2的整数对问题
问题描述:
小S需要找到在两个整数 L 和 R 之间是否存在两个整数,其按位 XOR 运算的结果为 2。你的任务是判断是否存在这样的整数对。如果存在,返回 1;否则,返回 0。
例如,给定 L = 2 和 R = 7,(4, 6) 的按位 XOR 结果为 2,并且 4 和 6 都在范围内。因此,答案为 1。
def solution(L: int, R: int) -> int:
# 遍历范围内的所有数对 (a, b)
for a in range(L, R + 1):
for b in range(a + 1, R + 1): # 确保 b > a 以避免重复计算
# 检查 a 和 b 的 XOR 结果是否为 2
if a ^ b == 2:
return 1 # 如果找到满足条件的数对,返回 1
return 0 # 如果没有找到满足条件的数对,返回 0
if __name__ == '__main__':
print(solution(L = 2, R = 7) == 1)
print(solution(L = 1, R = 4) == 1)
print(solution(L = 5, R = 10) == 1)
试题3:桥梁最高高度
问题描述:
牛妹需要用 n 根桥柱搭建一座桥,第一根桥柱和最后一根桥柱的高度已经确定,分别为 a 和
b。为了保证桥梁的稳固性,相邻桥柱的高度差不能超过 1。牛妹想知道,在保证稳固性的前提下,桥梁中最高的桥柱能有多高。你需要帮助牛妹计算桥梁最高的桥柱的高度。
def solution(n: int, a: int, b: int) -> int:
# 计算高度差
diff = abs(a - b)
# 判断是否可以搭建桥梁
if diff > n - 1:
return -1
# 计算最高桥柱高度
max_height = max(a, b) + (n - 1 - diff) // 2
return max_height
试题4:歌曲时长配对问题
问题描述:
小F有一个由歌曲组成的列表,每首歌的持续时间用数组 time 表示,其中第 i 首歌的时长为 time[i] 秒。她想知道列表中有多少对歌曲的总持续时间能够被 10 整除。具体来说,我们希望找到所有满足 i < j 且 (time[i] + time[j]) % 10 == 0 的配对。
例如,给定 time = [3, 2, 15, 1, 4],有一对歌曲(time[2] 和 time[4])的时长和为 19 秒,能够被 10 整除。
def solution(time: list) -> int:
# 初始化一个字典来记录每个余数的出现次数
remainder_count = {}
pair_count = 0
for t in time:
# 计算当前歌曲时长的余数
remainder = t % 10
# 计算互补余数
complement_remainder = (10 - remainder) % 10
# 检查互补余数是否在字典中,如果在则增加配对计数
if complement_remainder in remainder_count:
pair_count += remainder_count[complement_remainder]
# 更新当前余数的计数
if remainder in remainder_count:
remainder_count[remainder] += 1
else:
remainder_count[remainder] = 1
return pair_count
if __name__ == '__main__':
print(solution(time=[3, 2, 15, 1, 4]) == 0)
print(solution(time=[10, 20, 30]) == 3)
print(solution(time=[7, 3, 5, 5, 10]) == 2)
试题5:正整数切割方案问题
问题描述:
小R需要将一个正整数切割成两部分,使得这两部分的和为偶数。小R想知道有多少种合法的切割方案。注意,切割后的正整数可以出现前导零。
def solution(num: str) -> int:
count = 0
# 遍历所有可能的切割位置
for i in range(1, len(num)):
part1 = num[:i]
part2 = num[i:]
# 判断两部分的和是否为偶数
if (int(part1) % 2 == 0 and int(part2) % 2 == 0) or (int(part1) % 2 != 0 and int(part2) % 2 != 0):
count += 1
return count
if __name__ == '__main__':
print(solution(num = "103") == 1)
print(solution(num = "2406") == 3)
print(solution(num = "5001") == 1)
试题6:活字字模印刷
问题描述:
小U最近迷上了活字印刷,他拥有一套活字字模,其中每个字模上都刻有一个字母。给定一个字符串 tiles 表示字母序列,每个字母代表一个字模,小U想知道用这些字模最多可以印出多少种不同的非空字母序列。
注意:每个字模只能使用一次。
def solution(tiles: str) -> int:
# 使用集合来存储所有不同的子序列
unique_sequences = set()
def backtrack(path, remaining_tiles):
# 如果当前路径不为空,则将其加入集合
if path:
unique_sequences.add(path)
# 遍历剩余的字符
for i in range(len(remaining_tiles)):
# 选择当前字符,并递归处理剩余字符
# 这里需要跳过已经选择的字符
backtrack(path + remaining_tiles[i], remaining_tiles[:i] + remaining_tiles[i+1:])
# 从空路径开始,递归生成所有子序列
backtrack("", tiles)
# 返回集合的大小,即所有不同的非空子序列的数量
return len(unique_sequences)
if __name__ == '__main__':
print(solution(tiles="AAB") == 8)
print(solution(tiles="ABC") == 15)
print(solution(tiles="AAABBC") == 188)
print(solution(tiles="AAABCBD") == 1265)
试题7:独特橡皮泥士兵
问题描述:
小R有一组橡皮泥士兵,它们的大小各不相同或非常接近。为了让每个士兵都更具独特性,小R希望确保所有士兵的大小都不相同。小R可以通过增加某些士兵的大小来实现这一目标。每次操作可以给某个士兵加一单位橡皮泥,以增加其大小。
给定士兵的数量n和每个士兵当前的大小的数组a,计算为了使所有士兵的大小都不同,至少需要增加多少单位橡皮泥。
def solution(n: int, a: list) -> int:
# 1. 对数组进行排序
a.sort()
total_increment = 0
# 2. 遍历排序后的数组
for i in range(1, n):
if a[i] <= a[i - 1]:
# 3. 计算需要增加的大小
increment = a[i - 1] - a[i] + 1
a[i] += increment
total_increment += increment
return total_increment
if __name__ == '__main__':
print(solution(5, [1, 1, 2, 3, 3]) == 5)
print(solution(6, [4, 4, 4, 5, 5, 6]) == 11)
print(solution(7, [10, 20, 10, 30, 40, 30, 20]) == 3)
试题8:珠子颜色去重
问题描述:
小S拥有一条由n颗珠子组成的手链,每颗珠子都有一个对应的颜色编号。她希望将手链上相同颜色的珠子进行去重,只保留每种颜色最后出现的那颗珠子,同时保持珠子原来的相对顺序。
例如,如果珠子的颜色编号是 [1, 2, 1, 3, 4, 2, 4, 4],去重后的珠子颜色应该是 [1, 3, 2, 4]。
def solution(n: int, a: list) -> list:
# 创建一个字典来记录每种颜色最后出现的位置
last_occurrence = {}
# 遍历珠子列表,记录每种颜色最后出现的位置
for i in range(n):
last_occurrence[a[i]] = i
# 创建一个结果列表来存储去重后的珠子颜色
result = []
# 再次遍历珠子列表,根据记录的最后出现位置来决定是否保留该颜色
for i in range(n):
if last_occurrence[a[i]] == i:
result.append(a[i])
return result
if __name__ == '__main__':
print(solution(n = 8, a = [1, 2, 1, 3, 4, 2, 4, 4]) == [1, 3, 2, 4])
print(solution(n = 5, a = [5, 5, 5, 5, 5]) == [5])
print(solution(n = 6, a = [6, 1, 2, 6, 1, 2]) == [6, 1, 2])