大厂真题 / 蔚来
蔚来 4.19 笔试真题 - 通用岗
本场考试概述
考试时间:2026年4月19日 考试岗位:通用岗 难度评级:中等
考点分析:
- 第一题:排序(难度中等)
- 第二题:日期枚举 + 模拟(难度中等)
建议策略:
- 第一题核心在于把链表转为数组后利用 Python 内置的字典序比较直接排序,无需手写比较器
- 第二题逐年枚举生日日期,重点处理”出生前不算”和”闰年2月29日在非闰年改为2月28日”两个边界条件
第一题:链表排序
题目描述
给定 n 个链表,将它们按字典序从小到大排序后输出。
链表的字典序定义如下:若两个链表的前 k 个节点相同(k 可以为 0),且第 k+1 个节点不同,则第 k+1 个节点数值更小的那个链表字典序更小。若链表 A 是链表 B 的前缀,则 A 的字典序比 B 小。
第一行输入整数 n 表示链表数量。接下来 n 行,每行第一个整数 k 表示链表长度,后跟 k 个整数表示链表节点的值。
样例
输入
5
2 1 2
2 2 1
1 2
1 1
1 0
输出
0
1
1 2
2
2 1
思路分析
第一步:观察问题本质
题目要求对链表排序,但链表只能从头顺序访问,不支持随机访问,不方便做排序时的元素比较。链表长度最大只有 1000,总节点数可控,直接把每个链表的节点值按顺序存入数组,后续在数组上操作。
第二步:字典序比较
题目定义的链表字典序和数组的字典序规则完全一致:从第一个位置开始逐个比较,找到第一个不同的位置,值小的排前面;如果所有对应位置都相同,较短的排前面(前缀字典序更小)。Python 的列表天然支持字典序比较——两个 list 用 < 比较时,会逐元素比对,长度不同时短的更小,正好符合题意。
第三步:实现
读入所有链表转成数组列表,调用 sort() 排序,逐行输出即可。
题解代码
import sys
input = sys.stdin.readline
n = int(input())
lists = []
for _ in range(n):
parts = list(map(int, input().split()))
k = parts[0]
lists.append(parts[1:k + 1])
lists.sort()
out = []
for lst in lists:
out.append(" ".join(map(str, lst)))
print("\n".join(out))
复杂度分析
时间复杂度:O(n * k * log n),排序进行 O(n log n) 次比较,每次比较最多遍历 k 个元素。 空间复杂度:O(n * k),存储所有链表转成的数组。
第二题:过生日
题目描述
给定出生日期(年、月、日),以及一个查询区间 [起始日期, 截止日期],统计在该区间内过了多少次生日。
规则:出生当天算第 0 岁生日(也计入次数),出生前的年份不算生日。如果出生在闰年的 2 月 29 日,则在非闰年改为 2 月 28 日过生日,在闰年仍为 2 月 29 日。
多组数据,每组第一行输入三个整数表示出生年月日,第二行输入六个整数表示查询起始日和截止日。年份范围 1~3000。
样例
输入
1
1993 9 21
1990 1 1 2000 12 31
输出
8
思路分析
第一步:分析约束规模
年份范围最大 3000,每年最多过一次生日,因此逐年枚举完全可行,无需高级算法。
第二步:日期编码
要判断一个日期是否落在查询区间内,需要一种能直接比大小的日期表示。将日期 (y, m, d) 编码为整数 y * 10000 + m * 100 + d,年份占高位、月份占中间、日占低位,两个日期的先后关系等价于编码后整数的大小关系。选这种编码而不是转天数,是因为只需比较先后,不需要算间隔。
第三步:闰年 2 月 29 日特殊处理
如果出生在闰年 2 月 29 日,非闰年没有 2 月 29 日,题目规定改为 2 月 28 日过生日。判断闰年的规则:能被 4 整除且不能被 100 整除,或者能被 400 整除。
第四步:逐年枚举 + 三条件判断
遍历查询区间覆盖的每一年 yr,算出该年的生日日期编码 cur,检查三个条件是否全部满足:
- cur >= start(生日不早于查询起始日)
- cur <= end(生日不晚于查询截止日)
- cur >= birth(生日不早于出生日——还没出生不能算过生日)
三个条件缺一不可。条件 3 容易遗漏:查询起始日可能早于出生日(如样例中 1990 年开始查询但 1993 年才出生),1990~1992 年虽然在区间内但还没出生,不计入。
题解代码
import sys
input = sys.stdin.readline
def is_leap(y):
return (y % 4 == 0 and y % 100 != 0) or y % 400 == 0
def to_num(y, m, d):
return y * 10000 + m * 100 + d
def solve():
y, m, d = map(int, input().split())
a1, b1, c1, a2, b2, c2 = map(int, input().split())
birth = to_num(y, m, d)
start = to_num(a1, b1, c1)
end = to_num(a2, b2, c2)
count = 0
for yr in range(a1, a2 + 1):
bd = d
# 闰年2月29日出生,非闰年改为2月28日
if m == 2 and d == 29 and not is_leap(yr):
bd = 28
cur = to_num(yr, m, bd)
if start <= cur <= end and cur >= birth:
count += 1
print(count)
T = int(input())
for _ in range(T):
solve()
复杂度分析
时间复杂度:O(T * Y),T 组数据,每组枚举 Y 年(最大约 3000),每年 O(1) 判断。 空间复杂度:O(1),只用了几个整数变量。
小结
- 第一题链表排序,核心技巧是把链表转为数组后利用 Python 内置的字典序比较直接排序,无需手写比较逻辑
- 第二题过生日计数,逐年枚举即可,关键是处理好三个边界条件:查询区间约束、出生前不算、闰年 2 月 29 日的特殊过生日规则