【备战春招必看】字节跳动2025届第5套笔试解析 | 大厂真题通关指南
✅ 字节跳动春招备战指南 ✅
💡 学习建议:
- 先尝试独立解题(建议用时:90分钟/套)
- 对照解析查漏补缺
- 配套练习题库
互联网必备刷题宝典🔗
📢 字节跳动技术岗笔试重要信息速览
⏰ 笔试时间安排
- 常规场次:每周六交替进行
- 上午场 10:00~12:00
- 晚间场 19:00~21:00
- 通知时间:提前2天通过邮箱发送考试链接
🧩 笔试题型分布
算法岗 | 选择题 + 4道编程 |
后端开发岗 | 选择题 + 3道编程 |
前端/测试岗 | 选择题 + 4道编程 |
⚙️ 考试设置要点
- 考试平台:牛客网(ACM模式)
- 监考要求:
- 必须开启笔记本前置摄像头
- 禁止使用手机(需小程序锁定)
- 允许使用本地IDE
- 编程规范:
- 严格遵循输入输出格式
- 注意时间复杂度控制(通常1s对应1e8次运算)
📚 笔试经验贴
(所有展示题面均已进行改编处理,保留核心考点)
本题库收录整理自:
- 互联网公开的笔试真题回忆版(经网友投稿)
- 各大技术社区公开讨论的经典题型
- 历年校招考生提供的解题思路
🔍 题库特点:
- 100%真实笔试场景还原
- 包含高频考点题型
- 提供多语言实现参考
- 持续更新2024届最新真题
⚠️ 注意事项:
- 所有题目均来自公开渠道,已进行改编脱敏处理
- 实际笔试可能出现题型变化,请以官方通知为准
题目 1:钱包购物问题
题目内容
小基有 个钱包,其中第
个钱包装了
元,他每天都会恰好使用一个钱包中的钱去购物,尽可能多地购买一种单价为
元的物品,日复一日,直到所有钱包中的钱都分别买不起此物品。
在小基在开始日复一日地购物前,可以向任意一些钱包中再加入一些钱,但总共加入的钱数不超过 。
现在小基想知道,如果自己以最优方案向钱包中加钱,那么最多可以购买多少件此物品。
输入描述
第一行输入三个整数 、
和
(
;
;
)表示小基的钱包个数、要购买的物品单价,以及小基最多可以提前加入钱包中的钱。
第二行输入 个正整数
表示小基每个钱包的钱数。
输出描述
在一行输出一个整数,表示小基最多可以购买的此物品数量。
样例1
输入
5 3 2
4 4 3 1 2
输出
4
说明 可以提前向第五个钱包中加入 元,各个钱包变成
,此时用每个钱包日复一日购买这个单价为
的物品,显然最多可以买
个。 全都不能买时,各个钱包为:
。
样例2
输入
3 10 0
9 6 3
输出
0
题解
这道题目的关键是理解如何最优地分配额外的钱。
主要思路是贪心:
- 对于每个钱包,计算它能买多少个物品,以及剩余的钱
- 优先补充那些剩余钱较多的钱包,因为这样可以用最少的钱让它多买一个物品
- 如果还有剩余的钱,就用来购买新的物品
时间复杂度:,主要来自排序。对于给定的数据范围(
)是完全可以接受的。
代码实现
C++
long long max_items(vector<int>& wallets, int k, long long extra) {
int n = wallets.size();
vector<pair<int, int>> remain(n);
long long total = 0;
// 计算每个钱包能买多少个物品和剩余的钱
for(int i = 0; i < n; i++) {
int items = wallets[i] / k;
int rem = wallets[i] % k;
total += items;
remain[i] = {rem, i};
}
// 按剩余钱数从大到小排序
sort(remain.rbegin(), remain.rend());
// 优先补充剩余钱较多的钱包
for(int i = 0; i < n && extra >= 0; i++) {
int need = k - remain[i].first;
if(need <= extra) {
extra -= need;
total++;
}
}
// 剩余的钱用来购买新物品
total += extra / k;
return total;
}
Python
def max_items(wallets, k, extra):
n = len(wallets)
remain = []
total = 0
# 计算每个钱包能买多少个物品和剩余的钱
for i in range(n):
items = wallets[i] // k
rem = wallets[i] % k
total += items
remain.append((rem, i))
# 按剩余钱数从大到小排序
remain.sort(reverse=True)
# 优先补充剩余钱较多的钱包
for rem, idx in remain:
need = k - rem
if need <= extra:
extra -= need
total += 1
# 剩余的钱用来购买新物品
total += extra // k
return total
Java
public class Solution {
public long maxItems(int[] wallets, int k, long extra) {
int n = wallets.length;
long total = 0;
int[][] remain = new int[n][2];
// 计算每个钱包能买多少个物品和剩余的钱
for(int i = 0; i < n; i++) {
int items = wallets[i] / k;
int rem = wallets[i] % k;
total += items;
remain[i] = new int[]{rem, i};
}
// 按剩余钱数从大到小排序
Arrays.sort(remain, (a, b) -> b[0] - a[0]);
// 优先补充剩余钱较多的钱包
for(int i = 0; i < n && extra >= 0; i++) {
int need = k - remain[i][0];
if(need <= extra) {
extra -= need;
total++;
}
}
// 剩余的钱用来购买新物品
total += extra / k;
return total;
}
}
题目 2:数组取反问题
题目内容
小基有一个长度为 的数组,每次可以选择其中
个数,将这
个数取反,小基想知道经过若干次操作之后,所有数字元素之和的最大是多少。
输入描述
第一行一个整数 ,数组长度为
。
第二行 个整数,表示数组元素。
输出描述
输出一个整数,表示所有数组元素之和的最大值。
样例1
输入
3
-1 -2 3 -4 -5
输出
15
说明 先选择前三个元素取反,再选择后三个元素取反,数组元素之和最大为 。
题解
这道题目的关键是理解如何通过取反操作使数组和最大。
主要思路:
- 如果有偶数个负数,可以全部变为正数
- 每次选择
个负数和
个正数取反
- 下一次选择另外
个负数和相同的正数取反
- 这样正数不变,负数全部变为正数
- 每次选择
- 如果有奇数个负数,一定会剩下一个负数
- 应该让绝对值最小的数为负数
时间复杂度:,主要来自排序。对于给定的数据范围(
)是完全可以接受的。
代码实现
C++
long long max_sum(vector<int>& nums) {
int n = (nums.size() + 1) / 2;
vector<int> pos, neg;
long long sum = 0;
int min_abs = INT_MAX;
// 分离正负数
for(int x : nums) {
if(x >= 0) pos.push_back(x);
else neg.push_back(x);
sum += abs(x);
min_abs = min(min_abs, abs(x));
}
// 如果负数个数为奇数,减去最小数的两倍
if(neg.size() % 2 == 1) {
sum -= 2 * min_abs;
}
return sum;
}
Python
def max_sum(nums):
n = (len(nums) + 1) // 2
pos = []
neg = []
total = 0
min_abs = float('inf')
# 分离正负数
for x in nums:
if x >= 0:
pos.append(x)
else:
neg.append(x)
total += abs(x)
min_abs = min(min_abs, abs(x))
# 如果负数个数为奇数,减去最小数的两倍
if len(neg) % 2 == 1:
total -= 2 * min_abs
return total
Java
public class Solution {
public long maxSum(int[] nums) {
int n = (nums.length + 1) / 2;
List<Integer> pos = new ArrayList<>();
List<Integer> neg = new ArrayList<>();
long sum = 0;
int minAbs = Integer.MAX_VALUE;
// 分离正负数
for(int x : nums) {
if(x >= 0) pos.add(x);
else neg.add(x);
sum += Math.abs(x);
minAbs = Math.min(minAbs, Math.abs(x));
}
// 如果负数个数为奇数,减去最小数的两倍
if(neg.size() % 2 == 1) {
sum -= 2L * minAbs;
}
return sum;
}
}
题目 3:奇妙树问题
题目内容
小基有一棵 个点的树,其中
号点是根。每个点有一个权值
。如果满足任意节点的权值大于等于其子节点的权值和,那么这棵树就是一棵奇妙树。
小基每次操作可以选择一个点,将其权值加一。请问小基最少需要多少次操作,才能使这棵树变成一棵奇妙树。
输入描述
第一行一个整数 ,表示树的节点数。
第二行 个整数
,表示每个点的权值。
接下来 行,每行两个整数
和
,表示
和
之间有一条边。
输出描述
输出一个整数,表示最少需要多少次操作。
样例1
输入
3
1 2 3
1 2
1 3
输出
4
说明 至少需要 次操作,将
号点的权值变为
。
题解
这道题目可以通过自底向上的 DFS 来解决。
主要思路:
- 从叶子节点开始,计算每个节点的子树权值和
- 如
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力