介绍
豆包青训营是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目,主要面向在校大学生。该项目的目标是培养具有职业竞争力的优秀开发工程师,并提供全程免费的课程,不收取任何费用。
课程内容和方向
豆包青训营的课程涵盖前端、后端和AI方向。在这个飞速发展的AI时代,学员将与豆包MarsCode团队一起深入探索技术领域,学习和运用AI,提高编程效率。此外,课程还包括大数据方向,适合对大数据感兴趣的学员学习,
本文提供训练营试题解析供参考
试题1:找单独的数
问题描述: 在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。
要求: 1.设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。 2.尽量减少额外空间的使用,以体现你的算法优化能力。
约束条件 1 ≤ cards.length ≤ 1001 0 ≤ cards[i] ≤ 1000 班级人数为奇数 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次
java
public class Main {
public static int solution(int[] cards) {
// 初始化结果变量为0
int result = 0;
// 遍历输入列表中的每个数字
for (int num : cards) {
// 对每个数字进行异或运算
result ^= num;
}
// 返回最终结果
return result;
}
public static void main(String[] args) {
// 添加你的测试用例
System.out.println(solution(new int[]{1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4);
System.out.println(solution(new int[]{0, 1, 0, 1, 2}) == 2);
}
}
试题2:数字字符串格式化
问题描述: 小M在工作时遇到了一个问题,他需要将用户输入的不带千分位逗号的数字字符串转换为带千分位逗号的格式,并且保留小数部分。小M还发现,有时候输入的数字字符串前面会有无用的 0,这些也需要精简掉。请你帮助小M编写程序,完成这个任务。
java
public class Main {
public static String solution(String s) {
// 去除前导零
s = s.replaceFirst("^0+(?!$)", "");
// 分割整数和小数部分
String[] parts = s.split("\\.");
String integerPart = parts[0];
String fractionalPart = parts.length > 1 ? parts[1] : "";
// 添加千分位逗号
StringBuilder sb = new StringBuilder();
for (int i = 0; i < integerPart.length(); i++) {
if (i > 0 && (integerPart.length() - i) % 3 == 0) {
sb.append(",");
}
sb.append(integerPart.charAt(i));
}
// 合并结果
if (fractionalPart.isEmpty()) {
return sb.toString();
} else {
return sb.toString() + "." + fractionalPart;
}
}
public static void main(String[] args) {
System.out.println(solution("1294512.12412").equals("1,294,512.12412"));
System.out.println(solution("0000123456789.99").equals("123,456,789.99"));
System.out.println(solution("987654321").equals("987,654,321"));
}
}
试题3:数字分组求偶数和
问题描述: 小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。
numbers: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。 例如对于[123, 456, 789],14个符合条件的数为:147 149 158 167 169 248 257 259 268 347 349 358 367 369。
python
def solution(numbers):
# 将每个数字组转换为数字列表
num_lists = [list(map(int, str(num))) for num in numbers]
# 递归函数,用于生成所有可能的组合
def generate_combinations(index, current_sum):
if index == len(num_lists):
# 检查当前组合的和是否为偶数
return 1 if current_sum % 2 == 0 else 0
count = 0
for num in num_lists[index]:
# 递归调用,选择当前数字组中的一个数字
count += generate_combinations(index + 1, current_sum + num)
return count
# 从第一个数字组开始生成组合
return generate_combinations(0, 0)
if __name__ == "__main__":
# 你可以添加更多测试用例
print(solution([123, 456, 789]) == 14)
print(solution([123456789]) == 4)
print(solution([14329, 7568]) == 10)
试题4:寻找最大葫芦
问题描述: 在一场经典的德州扑克游戏中,有一种牌型叫做"葫芦"。"葫芦"由五张牌组成,其中包括三张相同牌面值的牌 a 和另外两张相同牌面值的牌b。如果两个人同时拥有"葫芦",我们会优先比较牌 a 的大小,若牌 a相同则再比较牌 b 的大小。
在这个问题中,我们对"葫芦"增加了一个限制:组成"葫芦"的五张牌牌面值之和不能超过给定的最大值 max。牌面值的大小规则为:A > K > Q > J > 10 > 9 > ... > 2,其中 A 的牌面值为1,K 为13,依此类推。
给定一组牌,你需要找到符合规则的最大的"葫芦"组合,并输出其中三张相同的牌面和两张相同的牌面。如果找不到符合条件的"葫芦",则输出 "0, 0"。
python
def solution(n, max, array):
frequency = {}
frequency[1]=0
for card in array:
if card in frequency:
frequency[card] += 1
else:
frequency[card] = 1
x=0
y=0
if frequency[1] >= 3:
for b in frequency:
if b != 1 and frequency[b] >= 2:
# 计算总和
total = 3+ 2 * b
if total <= max:
# 比较并更新最佳结果
if b > y:
x = 1
y = b
return [x, y]
elif frequency[1] == 2:
for a in frequency:
if a != 1 and frequency[a] >= 3:
# 计算总和
total = 3*a+ 2
if total <= max:
# 比较并更新最佳结果
if a > x:
x = a
y = 1
return [x, y]
else:
for a in frequency:
if frequency[a] >= 3:
for b in frequency:
if a != b and frequency[b] >= 2:
# 计算总和
total = 3 * a + 2 * b
if total <= max:
# 比较并更新最佳结果
if a > x or (a == x and b > y):
x = a
y = b
return [x, y]
if __name__ == "__main__":
# Add your test cases here
print(solution(9, 34, [6, 6, 6, 8, 8, 8, 5, 5, 1]) == [8, 5])
print(solution(9, 37, [9, 9, 9, 9, 6, 6, 6, 6, 13]) == [6, 9])
print(solution(9, 40, [1, 11, 13, 12, 7, 8, 11, 5, 6]) == [0, 0])
试题5:创意标题匹配问题
问题描述: 在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的 bidword 对创意中的通配符(通配符是用成对 {} 括起来的字符串,可以包含 0 个或者多个字符)进行替换,用来提升广告投放体验。例如:"{末日血战} 上线送 SSR 英雄,三天集齐无敌阵容!",会被替换成"帝国时代游戏下载上线送 SSR 英雄,三天集齐无敌阵容!"。给定一个含有通配符的创意和n个标题,判断这句标题是否从该创意替换生成的。
python
import re
def solution(n, template, titles):
# 解析模板,找出所有的通配符
pattern = re.escape(template) # 先将模板中的特殊字符转义
pattern = pattern.replace(r'\{.*?\}', '.*?') # 将通配符部分替换为 .*?
# 生成正则表达式
regex = re.compile(pattern)
results = []
for title in titles:
# 使用正则表达式匹配标题
if regex.fullmatch(title):
results.append("True")
else:
results.append("False")
# 将结果列表转换为逗号分隔的字符串
return ",".join(results)
if __name__ == "__main__":
# 你可以添加更多测试用例
testTitles1 = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"]
testTitles2 = ["CLSomGhcQNvFuzENTAMLCqxBdj", "CLSomNvFuXTASzENTAMLCqxBdj", "CLSomFuXTASzExBdj", "CLSoQNvFuMLCqxBdj", "SovFuXTASzENTAMLCq", "mGhcQNvFuXTASzENTAMLCqx"]
testTitles3 = ["abcdefg", "abefg", "efg"]
print(solution(4, "ad{xyz}cdc{y}f{x}e", testTitles1) == "True,False,False,True")
print(solution(6, "{xxx}h{cQ}N{vF}u{XTA}S{NTA}MLCq{yyy}", testTitles2) == "False,False,False,False,False,True")
print(solution(3, "a{bdc}efg", testTitles3) == "True,True,False")
试题6:找出整形数组中占比超过一半的数
问题描述: 小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。
python
def solution(array):
# 创建一个字典来记录每个数字的出现次数
count_dict = {}
# 遍历数组,统计每个数字的出现次数
for num in array:
# 如果数字已经在字典中,增加其计数
if num in count_dict:
count_dict[num] += 1
else:
# 如果数字不在字典中,初始化其计数为1
count_dict[num] = 1
# 遍历字典,找到出现次数超过一半的数字
for num, count in count_dict.items():
if count > len(array) / 2:
return num
# 如果没有找到符合条件的数字,返回0(虽然题目保证一定存在这样的数字)
return 0
if __name__ == "__main__":
# 添加你的测试用例
print(solution([1, 3, 8, 2, 3, 1, 3, 3, 3]) == 3)
试题7:小F的永久代币卡回收计划
问题描述: 小F最近迷上了玩一款游戏,她面前有一个永久代币卡的购买机会。该卡片的价格为 a 勾玉,每天登录游戏可以返还 b 勾玉。小F想知道她至少需要登录多少天,才能让购买的永久代币卡回本。
python
import math
def solution(a: int, b: int) -> int:
# 使用向上取整来计算需要的天数
# 计算 a / b 并向上取整
days = math.ceil(a / b)
return days
if __name__ == '__main__':
print(solution(10, 1) == 10)
print(solution(10, 2) == 5)
print(solution(10, 3) == 4)
试题8:构造特定数组的逆序拼接
问题描述: 小U得到了一个数字n,他的任务是构造一个特定数组。这个数组的构造规则是:对于每个i从1到n,将数字n到i逆序拼接,直到i等于n为止。最终,输出这个拼接后的数组。
例如,当n等于3时,拼接后的数组是 [3, 2, 1, 3, 2, 3]。
python
def solution(n: int) -> list:
result = [] # 初始化结果列表
for i in range(1, n + 1): # 从1到n循环
# 生成从n到i的逆序序列
for j in range(n, i - 1, -1):
result.append(j) # 将逆序序列添加到结果列表中
return result # 返回结果列表
if __name__ == '__main__':
print(solution(3) == [3, 2, 1, 3, 2, 3])
print(solution(4) == [4, 3, 2, 1, 4, 3, 2, 4, 3, 4])
print(solution(5) == [5, 4, 3, 2, 1, 5, 4, 3, 2, 5, 4, 3, 5, 4, 5])
试题9:比赛配对问题
问题描述: 小R正在组织一个比赛,比赛中有 n 支队伍参赛。比赛遵循以下独特的赛制:
如果当前队伍数为 偶数,那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛,且产生 n / 2 支队伍进入下一轮。 如果当前队伍数为 奇数,那么将会随机轮空并晋级一支队伍,其余的队伍配对。总共进行 (n - 1) / 2 场比赛,且产生 (n - 1) / 2 + 1 支队伍进入下一轮。 小R想知道在比赛中进行的配对次数,直到决出唯一的获胜队伍为止。
python
def solution(n: int) -> int:
# 初始化配对次数
pairs = 0
# 循环直到队伍数变为1
while n > 1:
if n % 2 == 0:
# 偶数队伍数
pairs += n // 2 # 增加 n / 2 次配对
n = n // 2 # 更新队伍数为 n / 2
else:
# 奇数队伍数
pairs += (n - 1) // 2 # 增加 (n - 1) / 2 次配对
n = (n - 1) // 2 + 1 # 更新队伍数为 (n - 1) / 2 + 1
return pairs
if __name__ == '__main__':
print(solution(7) == 6)
print(solution(14) == 13)
print(solution(1) == 0)
试题10:DNA序列编辑距离
问题描述: 小R正在研究DNA序列,他需要一个函数来计算将一个受损DNA序列(dna1)转换成一个未受损序列(dna2)所需的最少编辑步骤。编辑步骤包括:增加一个碱基、删除一个碱基或替换一个碱基。
python
def solution(dna1, dna2):
m, n = len(dna1), len(dna2)
# 创建一个 (m+1) x (n+1) 的二维数组 dp
dp = [[0] * (n + 1) for _ in range(m + 1)]
# 初始化 dp 数组的第一行和第一列
for i in range(m + 1):
dp[i][0] = i
for j in range(n + 1):
dp[0][j] = j
# 填充 dp 数组
for i in range(1, m + 1):
for j in range(1, n + 1):
if dna1[i - 1] == dna2[j - 1]:
dp[i][j] = dp[i - 1][j - 1]
else:
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
# 返回 dp[m][n],即最少编辑步骤
return dp[m][n]
if __name__ == "__main__":
# 你可以添加更多测试用例
print(solution("AGCTTAGC", "AGCTAGCT") == 2)
print(solution("AGCCGAGC", "GCTAGCT") == 4)