介绍
豆包青训营是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目,主要面向在校大学生。该项目的目标是培养具有职业竞争力的优秀开发工程师,并提供全程免费的课程,不收取任何费用。
课程内容和方向
豆包青训营的课程涵盖前端、后端和AI方向。在这个飞速发展的AI时代,学员将与豆包MarsCode团队一起深入探索技术领域,学习和运用AI,提高编程效率。此外,课程还包括大数据方向,适合对大数据感兴趣的学员学习,
本文提供训练营试题解析供参考
试题1:英雄决斗的最大胜利次数
问题描述:
python
def solution(number, heroes):
# 对小F的英雄能力值进行排序
heroes.sort()
wins = 0
f_index = 0
# 遍历小U的英雄出场顺序
for u_hero in range(1, number + 1):
# 使用贪心策略选择小F的英雄
# 选择一个能力值刚好大于小U当前英雄能力值的英雄
while f_index < number and heroes[f_index] <= u_hero:
f_index += 1
if f_index < number:
wins += 1
f_index += 1
return wins
if __name__ == "__main__":
# 你可以添加更多测试用例
print(solution(7, [10,1,1,1,5,5,3]) == 4 )
print(solution(5, [1,1,1,1,1]) == 0 )
print(solution(10, [1,2,3,4,5,6,7,8,9,10]) == 9 )
试题2:数字魔法的加一操作
问题描述:
java
import java.math.BigInteger;
import java.util.LinkedList;
public class Main {
public static int solution(int n, int k, String numStr) {
LinkedList<Integer> list = new LinkedList<>();
for (char word : numStr.toCharArray()) {
int num = word - '0';
list.add(num);
}
// 使用内置方法反转链表
java.util.Collections.reverse(list);
// 逐位加一
for(int j=0;j<k;j++){
for (int i = 0; i < list.size(); i++) {
int value = list.get(i) + 1;
if (value <= 9) {
list.set(i, value);
} else if (value == 10) {
list.set(i, 0);
list.add(i + 1, 1);
i++;
}
}
}
// 再次反转回来
java.util.Collections.reverse(list);
// 构建 BigInteger 对象
StringBuilder sb = new StringBuilder();
for (Integer num : list) {
sb.append(num);
}
BigInteger number = new BigInteger(sb.toString());
BigInteger text = new BigInteger("1000000007");
// System.out.println(number.remainder(text).toString());
// //检查转换后数据的类型
// System.out.println(number.remainder(text).toString().getClass());
return number.remainder(text).intValue();
}
public static void main(String[] args) {
int result1 = solution(3, 1, "798");
System.out.println(result1 == 8109);
int result2 = solution(4, 1, "8109");
System.out.println(result2 == 92110);
int result3 = solution(5, 1, "92110");
System.out.println(result3 == 103221);
}
}
试题3:贪心的小包
问题描述:
python
def solution(N, M, data):
# 计算单个 data 数组的最大子数组和
def kadane(arr):
max_ending_here = max_so_far = arr[0]
for x in arr[1:]:
max_ending_here = max(x, max_ending_here + x)
max_so_far = max(max_so_far, max_ending_here)
return max_so_far
total_sum = sum(data)
max_single_sum = kadane(data)
max_prefix_sum = float('-inf')
current_prefix_sum = 0
for value in data:
current_prefix_sum += value
max_prefix_sum = max(max_prefix_sum, current_prefix_sum)
max_suffix_sum = float('-inf')
current_suffix_sum = 0
for value in reversed(data):
current_suffix_sum += value
max_suffix_sum = max(max_suffix_sum, current_suffix_sum)
# 根据 M 的值计算最终的最大子数组和
if M == 1:
return max_single_sum
else:
if total_sum > 0:
return max(max_single_sum, max_prefix_sum + max_suffix_sum + (M - 2) * total_sum)
else:
return max(max_single_sum, max_prefix_sum + max_suffix_sum)
if __name__ == "__main__":
# Add your test cases here
print(solution(5, 1, [1, 3, -9, 2, 4]) == 6)
print(solution(5, 3, [1, 3, -9, 2, 4]) == 11)
试题4:五子棋获胜策略
问题描述:
假设存在一个五子棋棋盘,大小未知。棋盘上已经摆放了一些白色棋子,现在你的手中还有一个白色棋子。你的任务是找出在棋盘的哪些位置摆放这个棋子,能够使棋盘上出现五颗棋子连成一线(不限于横向、纵向或斜向)。
备注:棋盘上当前不存在连成一条线的五个棋子,但至少存在一个点可以通过摆放使得形成五子连线。
java
import java.util.ArrayList;
import java.util.List;
public class Main {
// 检查某个位置是否可以形成五子连线
public static boolean canFormLine(int x, int y, int[][] board, int n) {
// 定义四个方向:右,下,右下,左下
int[][] directions = {{1, 0}, {0, 1}, {1, 1}, {1, -1}};
for (int[] dir : directions) {
int count = 1; // 当前位置记为1
int dx = dir[0], dy = dir[1];
// 检查正向
for (int step = 1; step < 5; ++step) {
int nx = x + dx * step;
int ny = y + dy * step;
if (nx >= 0 && nx < n && ny >= 0 && ny < n && board[nx][ny] == 1) {
count++;
} else {
break;
}
}
// 检查反向
for (int step = 1; step < 5; ++step) {
int nx = x - dx * step;
int ny = y - dy * step;
if (nx >= 0 && nx < n && ny >= 0 && ny < n && board[nx][ny] == 1) {
count++;
} else {
break;
}
}
// 如果形成五子连接,则返回 true
if (count >= 5) return true;
}
return false; // 没有符合条件的连线
}
// 主解决方案函数
public static int[][] solution(int n, int[][] board) {
List<int[]> results = new ArrayList<>();
// 检查每个位置是否能放置新棋子形成五子连线
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (board[i][j] == 0) { // 只检查空位
if (canFormLine(i, j, board, n)) {
results.add(new int[]{i + 1, j + 1}); // 记录行列,+1因要求从1开始
}
}
}
}
// 将结果转换为二维数组
int[][] resultArray = new int[results.size()][2];
for (int i = 0; i < results.size(); i++) {
resultArray[i] = results.get(i);
}
return resultArray.length > 0 ? resultArray : new int[][]{}; // 如果没有结果,返回 {-1, -1}
}
public static void main(String[] args) {
// 测试用例
int[][] array = {
{0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0}
};
int[][] expectedOutput = {{1, 1}, {6, 6}};
System.out.println(java.util.Arrays.deepEquals(solution(6, array), expectedOutput)); // 验证测试结果
}
}
试题5:机器人能量冒险
问题描述:
小R设计了一款有趣的机器人,它每次移动时至少需要消耗一个能量值。假设当小R为机器人提供了 5 个能量值,它可以选择不动,也可以走 1 步,但它不会走超过 5 步。
小R希望机器人能够走到一个终点,该终点位于 N 个位置的最后一个位置。每个位置上都有一定的能量值,机器人每次消耗当前位置的能量值可以往前走几步,之后可以继续消耗新的位置的能量继续前进。如果某个位置的能量值为 0,机器人将无法再继续行动。
小R想知道,机器人是否有可能通过这些能量值移动到最后一个位置。你能帮他计算一下吗?
java
public class Main {
public static String solution(int n, int[] array) {
int maxReach = 0;
for (int i = 0; i < n; i++) {
if (i > maxReach) {
return "FALSE";
}
maxReach = Math.max(maxReach, i + array[i]);
if (maxReach >= n - 1) {
return "TRUE";
}
}
return "FALSE";
}
public static void main(String[] args) {
System.out.println(solution(5, new int[] { 2, 3, 1, 1, 4 }).equals("TRUE"));
System.out.println(solution(5, new int[] { 3, 2, 1, 0, 4 }).equals("FALSE"));
}
}
试题6:最大乘积问题
问题描述:
java
import java.util.Stack;
public class Main {
public static int solution(int n, int[] array) {
int[] L = new int[n];
int[] R = new int[n];
// 初始化L和R数组
for (int i = 0; i < n; i++) {
L[i] = 0;
R[i] = 0;
}
// 单调栈计算L(i),从左到右
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && array[stack.peek()] <= array[i]) {
stack.pop();
}
L[i] = stack.isEmpty() ? 0 : stack.peek() + 1;
stack.push(i);
}
// 清空栈用于计算R(i)
stack.clear();
// 单调栈计算R(i),从右到左
for (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && array[stack.peek()] <= array[i]) {
stack.pop();
}
R[i] = stack.isEmpty() ? 0 : stack.peek() + 1;
stack.push(i);
}
// 计算 MAX(i) = L(i) * R(i) 并找出最大值
int maxProduct = 0;
for (int i = 0; i < n; i++) {
maxProduct = Math.max(maxProduct, L[i] * R[i]);
}
return maxProduct;
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution(5, new int[]{5, 4, 3, 4, 5})); // 输出: 8
System.out.println(solution(6, new int[]{2, 1, 4, 3, 6, 5})); // 输出: 15
System.out.println(solution(7, new int[]{1, 2, 3, 4, 5, 6, 7})); // 输出: 0
}
}