大厂真题 / 蔚来

蔚来 4.19 笔试真题 - 通用岗

本场考试概述

考试时间:2026年4月19日 考试岗位:通用岗 难度评级:中等

考点分析

  1. 第一题:排序(难度中等)
  2. 第二题:日期枚举 + 模拟(难度中等)

建议策略

  1. 第一题核心在于把链表转为数组后利用 Python 内置的字典序比较直接排序,无需手写比较器
  2. 第二题逐年枚举生日日期,重点处理”出生前不算”和”闰年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,检查三个条件是否全部满足:

  1. cur >= start(生日不早于查询起始日)
  2. cur <= end(生日不晚于查询截止日)
  3. 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 日的特殊过生日规则