TikTok OA 一亩三分地|27 NG CodeSignal 四题全解析
TikTok 2027 NG 的 OA 用 CodeSignal,70 分钟四题,前两题偏 Easy,第三题矩阵/内存模拟,第四题考思路和数据结构。本文逐题给出题意、思路、复杂度与代码,覆盖位积差、最长连续字符、内存分配释放与障碍物查询。
TikTok 2027 NG 的 OA 平台还是 CodeSignal,考试时间 70 分钟,共 4 道题。题型分布是熟悉的节奏:前两题偏 Easy,第三题是模拟,第四题更考思路和数据结构。CodeSignal 使用平台题库统一出题,只要公司采用 General Coding Assessment,就有机会碰到相同或相近的题目。
Q1:各位数字乘积减数字和
题意
给定正整数 n,分别计算它十进制每一位数字的乘积与数字和,返回「乘积 − 之和」。例如 123456 的乘积是 720、数字和是 21,结果为 699;1010 含 0,乘积为 0、数字和为 2,结果为 -2。
思路
用 list(map(int, str(n))) 拆成数字列表,遍历一次分别求乘积与总和,返回乘积减总和。含 0 时乘积自然为 0,无需单独处理。
def digit_product_minus_sum(n):
prod, total = 1, 0
for d in map(int, str(n)):
prod *= d
total += d
return prod - total
时间与空间均为 O(log n)(数字位数)。注意乘积初始化为 1、和初始化为 0。
Q2:最长连续相同字符
题意
给定只含小写字母的字符串,找出由同一字符连续组成的最长片段;若最长片段有多个,取最靠右的那个,返回「字符 + 连续次数」,例如连续三个 c 返回 c3。
思路
遍历并维护当前连续字符及其长度。遇到相同字符长度加一,遇到不同字符更新当前字符并重置为 1;同步记录全局最长。由于「相同长度取最靠右」,更新条件用「>=」让靠右者覆盖靠左者即可。
def longest_run(s):
best_ch, best_len = '', 0
cur_ch, cur_len = '', 0
for ch in s:
if ch == cur_ch:
cur_len += 1
else:
cur_ch, cur_len = ch, 1
if cur_len >= best_len:
best_ch, best_len = cur_ch, cur_len
return best_ch + str(best_len)
时间 O(n),空间 O(1)。
Q3:内存分配与释放
题意
模拟一段内存的分配和释放。alloc x 要找最靠左的连续 x 个空闲位置并占用,成功返回起始下标,同时为这次分配生成递增 ID;找不到返回 -1。erase ID 根据 ID 找到此前分配的整块内存并释放,返回释放长度;ID 不存在或已释放返回 -1。
思路
分配时从左到右遍历数组,用计数器记录连续空闲位置长度,遇到已占用位置清零;连续空闲长度达到要求时标记整段为已占用,用哈希表保存分配 ID 对应的起点和长度。释放时通过 ID 定位内存段,把对应位置清空并删除映射。
class Allocator:
def __init__(self, n):
self.mem = [0] * n
self.blocks = {}
self.next_id = 0
def alloc(self, x):
run = 0
for i in range(len(self.mem)):
if self.mem[i] == 0:
run += 1
if run == x:
start = i - x + 1
for j in range(start, i + 1):
self.mem[j] = 1
self.blocks[self.next_id] = (start, x)
self.next_id += 1
return start
else:
run = 0
return -1
def erase(self, id_):
if id_ not in self.blocks:
return -1
start, length = self.blocks.pop(id_)
for i in range(start, start + length):
self.mem[i] = 0
return length
alloc 最坏 O(n),erase O(length)。释放后映射要删除,重复 erase 要返回 -1。
Q4:障碍物区间查询
题意
给定有序维护的障碍物位置,支持「新增障碍物」与「查询区间 [x-size, x-1] 内是否存在障碍物」。查询时二分找到 x 左侧最近的障碍物,判断它是否落在区间内。
思路
用有序数组维护障碍物位置,新增通过 bisect.insort 插入;查询用二分定位左边界最近的障碍物,判断是否落在 [x-size, x-1] 内。查询 O(log n),但数组插入需要移动元素,插入 O(n);若要求插入也 O(log n),改用平衡树等有序集合。
import bisect
class Obstacles:
def __init__(self):
self.pos = []
def add(self, p):
bisect.insort(self.pos, p)
def has_in_range(self, x, size):
i = bisect.bisect_left(self.pos, x - size)
return i < len(self.pos) and self.pos[i] <= x - 1
FAQ
70 分钟四题怎么分配时间?
前 5 分钟浏览分流,先做能稳定通过的题;每做完一题跑样例和边界;最后留 5 到 8 分钟只做反例与提交检查,不要在卡住的题上硬耗。
Q4 为什么插入是 O(n)?
有序数组插入要在中间移动元素;查询只需二分。若题面要求插入和查询都 O(log n),要换成平衡树、跳表或动态开点线段树等有序集合结构。
参考来源
- LeetCode 3 — Longest Substring Without Repeating Characters
- LeetCode 146 — LRU Cache
- LeetCode 715 — Range Module
联系 VOPathway
如果你希望把这套方法用于自己的 OA 或 VO 准备,可以把目标岗位、当前阶段、面试时间和主要难点发给 VOPathway,我们会据此安排针对性的练习与复盘。
- 微信:Coding0201
- 邮箱:[email protected]
- Telegram:@OAVOProxy
- WhatsApp:+86 178 6396 8105
可提供 OA辅助、OA辅导、VO辅助与 VO辅导。文章用于训练参考,不代表相关公司的官方流程;实际安排请以候选人收到的通知为准。
本文用于面试准备与训练复盘。公司名称仅用于标识题型素材主题,不代表官方合作或录用承诺。
预约一次训练复盘 ↗