← 返回博客列表 Meta SDE NG VO 真题:归并排序变体 + 滑动窗口最大值
Meta

Meta SDE NG VO 真题:归并排序变体 + 滑动窗口最大值

2026-06-15

Meta 的 SDE New Grad VO 不只考你会不会写算法,更看你怎么读题、怎么拆题。这篇按 oavoservice 学员的一场 Meta SDE NG VO 复盘,挑两道真题讲清思路:第一题是归并排序的"非典型变体",第二题是经典的滑动窗口最大值(LeetCode 239)。两题放一起,正好覆盖"包装已有逻辑"和"换数据结构做优化"两类最常见的 follow-up 套路。文末附 VO辅助 / VO代面 的对接路径,给正在大厂求职、刷题备考的同学一个实战参考。


一、Meta SDE NG VO 概览

维度 详情
形式 远程视频面试(Coderpad / 共享编辑器)
时长 单轮约 45 分钟,2 道编程题
语言 自选,多数人用 Python
考察 读题拆题、边界处理、复杂度优化、沟通表达
风格 题面可能"非典型",重点看你能否抓住真正的考点

Meta NG 的编程轮节奏快,一轮经常要在 45 分钟内吃掉两道题。面试官给的题面不一定是 LeetCode 原题,反而常常故意包装一下,看你能不能剥开外壳、定位到真正要考的核心逻辑。

二、题一:归并排序的非典型变体(输入输出包装)

题目

先给一个非常简单的题:给定一个 list,纯排序,用 Python 实现。面试官明确要求写 merge sort(归并排序)。

写完之后是 follow-up:这个 list 里不只有 int,还会混入 char(字符),要求一并排好序。

拆题:他到底想考什么?

这不是一个典型算法题。遇到这种被刻意包装过的题,脑子里第一件事应该是——他想考的到底是什么?

对这道题来说,考点很清楚:在不改动已有核心算法的前提下,如何做合适的输入 / 输出处理。说人话,就是要你做一层类似 "API 网关" 的逻辑:

  1. 进来时把 charord() 统一转成 int
  2. 复用原封不动的 merge sort 核心;
  3. 出去时再用 chr() 把当初是字符的元素转回去。

抓住这个重点,实现本身没有奇技淫巧。关键是把"包装输入输出"的逻辑抽成单独的函数,让 merge sort 主体保持干净、逻辑清晰。

Python 解法

先是不动的归并排序核心:

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return _merge(left, right)

def _merge(left, right):
    merged = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            merged.append(left[i]); i += 1
        else:
            merged.append(right[j]); j += 1
    merged.extend(left[i:])
    merged.extend(right[j:])
    return merged

再把输入输出包装抽成一个独立函数,merge sort 完全不用改:

def sort_mixed(items):
    # 1) 包装输入:记下哪些位置原本是 char,统一转成 int 的可比较键
    encoded = []
    is_char = []
    for x in items:
        if isinstance(x, str):
            encoded.append(ord(x))
            is_char.append(True)
        else:
            encoded.append(x)
            is_char.append(False)

    # 2) 复用核心:但要让排序后还能知道某个值原本是不是 char
    #    所以排的是 (值, 原本是否为 char) 的二元组
    pairs = list(zip(encoded, is_char))
    pairs = merge_sort(pairs)   # 元组按第一维比较,天然可用

    # 3) 包装输出:原本是 char 的,用 chr 转回去
    return [chr(v) if was_char else v for v, was_char in pairs]

要点:把 (值, 是否为char) 打包成元组送进 merge sort,元组天然按第一维比较,核心逻辑零改动;解码时只看第二维决定要不要 chr() 还原。

print(sort_mixed([3, 'a', 1, 'Z', 2]))
# [1, 2, 3, 'Z', 'a']   ord('Z')=90 < ord('a')=97

时间复杂度:O(n log n)(归并排序主导)。空间复杂度:O(n)(编码数组 + 归并临时数组)。

三、题二:滑动窗口最大值(单调队列)

题目

LeetCode 239。给整数数组 nums 和窗口大小 k,窗口从数组左侧每次向右滑动一格,返回每个窗口内的最大值组成的数组。

拆题:优化点只有一个

最直观的做法是每个窗口都求一次最大值,时间复杂度 O(nk)。做优化的关键永远在思路:这题真正能优化的点只有把那个 k 干掉——也就是把"窗口内求最大值"从 O(k) 降到 O(1)。

于是需求很明确,要一个数据结构能做到:

  1. 只保留"后面还可能成为最大值"的元素,并保持有序;
  2. 队首 O(1) 取最大值,从队尾 O(1) 插入新元素 / 弹出更小的元素

能同时满足这两点的,就是用 deque 实现的单调队列(单调递减队列)。

Python 解法

队列里存下标,对应的值从队首到队尾单调递减:

from collections import deque

def max_sliding_window(nums, k):
    dq = deque()      # 存下标,nums[dq] 单调递减
    res = []
    for i, x in enumerate(nums):
        # 队尾比当前小的都没用了,弹掉(保证单调递减)
        while dq and nums[dq[-1]] <= x:
            dq.pop()
        dq.append(i)
        # 队首滑出窗口了就弹掉
        if dq[0] <= i - k:
            dq.popleft()
        # 窗口成形后,队首就是当前窗口最大值
        if i >= k - 1:
            res.append(nums[dq[0]])
    return res

三个细节:队尾维护单调性(更小的元素永远轮不到它当最大值,直接丢);队首检查是否已滑出窗口;下标走到 k-1 后才开始记录答案。

print(max_sliding_window([1, 3, -1, -3, 5, 3, 6, 7], 3))
# [3, 3, 5, 5, 6, 7]

时间复杂度:O(n)(每个下标最多进队、出队各一次)。空间复杂度:O(k)。

四、临场提醒


FAQ

Q1:Meta SDE NG VO 一轮考几道题?难度如何?

编程轮通常一轮约 45 分钟、2 道题,难度集中在 LeetCode 中等,偶有中上。重点不在题难,而在读题、拆题和沟通——题面常被刻意包装,考你能不能定位真正的考点。

Q2:第一题这种"归并排序里混 char"算偏题吗?怎么准备?

不算偏题,它考的是"在不改核心算法的前提下做输入输出包装"的工程思维。准备时多练把通用算法套到变形输入上,习惯用 ord / chr、元组打包等手段做转换,并把包装逻辑抽成独立函数。

Q3:滑动窗口最大值为什么要用单调队列?

因为唯一的优化点是把"窗口内求最大值"从 O(k) 降到 O(1)。单调队列(deque 实现)能在队首 O(1) 拿最大值、队尾 O(1) 插入和弹出,整体把 O(nk) 降到 O(n),是这类问题的标准解法。

Q4:Meta VO 用什么平台?可以用 Python 吗?

多数轮次在 Coderpad 或共享编辑器里进行,语言自选,绝大多数人用 Python。需要限时 mock、逐题讲解或 VO辅助 / VO代面 全程对接,可以走下面的路径定制。


正在准备 Meta SDE NG VO?

Meta NG 编程轮节奏快、题面爱包装,吃的是"拆题 + 沟通 + 代码组织"。oavoservice 提供 Meta 全流程陪练:归并排序变体 / 滑动窗口 / 单调队列 / 哈希等高频题限时模拟,Coderpad 环境与拆题表达逐题讲解,按 NG 岗题型做预测。教练含大厂资深工程师,支持 VO辅助 / VO代面 全程对接。

立即添加微信 Coding0201获取 Meta 真题与陪练

联系方式