這波 TikTok SDE NG 面試一共三輪,整體偏硬核。前兩輪都是純 coding,每輪兩道演算法題,時間卡得比較緊,考察重點在思路清晰度和程式碼完整性;題型以中高頻演算法為主,需要對複雜度和邊界比較敏感。第三輪是 HM 面,從履歷深挖專案經歷,重點問 infra 背景與系統設計思路。下面逐題複盤。
一、第一輪 Coding
Q1:最多改一個元素,判斷陣列是否有序
題目:在允許最多修改陣列一個元素的條件下,這個陣列能否變成非遞減有序?
從前往後遍歷,找到第一個違反非遞減的位置 i(即 nums[i] < nums[i-1])。此時有兩種修復方式:把 nums[i-1] 調小到 nums[i],或把 nums[i] 調大到 nums[i-1]。選哪種取決於 nums[i-2]:
def check_possibility(nums) -> bool:
changed = False
for i in range(1, len(nums)):
if nums[i] < nums[i - 1]:
if changed: # 已經改過一次,第二次違反 -> 失敗
return False
changed = True
# 優先把 nums[i-1] 壓到 nums[i](不破壞更前面的序)
if i >= 2 and nums[i - 2] > nums[i]:
nums[i] = nums[i - 1] # 只能抬高 nums[i]
else:
nums[i - 1] = nums[i]
return True
時間 O(n)、空間 O(1)。關鍵是貪心選哪個改,不要無腦改後面那個。
Q2:樹中到其他節點平均距離最小的節點
題目:找到樹中「到其他所有節點平均距離最小」的節點,一條邊算 1,要求 O(n)。
這是經典換根 DP(rerooting):先一次 DFS 求出根到所有節點的距離和 sum0 與每棵子樹大小;再一次 DFS 換根,父節點答案推子節點:ans[child] = ans[parent] + (n - 2*size[child])。距離和最小的節點即答案。
def min_avg_distance(n, edges):
g = [[] for _ in range(n)]
for u, v in edges:
g[u].append(v); g[v].append(u)
size = [1] * n
ans = [0] * n
def dfs1(u, p, depth):
ans[0] += depth
for w in g[u]:
if w != p:
dfs1(w, u, depth + 1)
size[u] += size[w]
def dfs2(u, p):
for w in g[u]:
if w != p:
ans[w] = ans[u] + n - 2 * size[w]
dfs2(w, u)
dfs1(0, -1, 0)
dfs2(0, -1)
return ans.index(min(ans))
兩次 DFS 共 O(n),避免對每個節點單獨 BFS 的 O(n²)。
二、第二輪 Coding
面試官先 2 分鐘閒聊(問最近專案裡怎麼最佳化資料庫查詢效能),然後直接進編碼。
Q1:巢狀整數列表迭代器
題目:給定巢狀整數列表(元素是整數或巢狀列表),實現迭代器按順序遍歷所有整數,自己定義資料結構並實現 next() 和 hasNext()。
用堆疊逆序壓入元素,hasNext() 時迴圈展開列表,直到堆疊頂是整數:
class NestedIterator:
def __init__(self, nestedList):
# 逆序壓堆疊,堆疊頂始終是下一個待處理元素
self.stack = nestedList[::-1]
def next(self) -> int:
# hasNext() 保證堆疊頂是整數,直接彈出
return self.stack.pop()
def hasNext(self) -> bool:
while self.stack:
top = self.stack[-1]
if isinstance(top, int):
return True
# 堆疊頂是列表:彈出並逆序壓回其內容
self.stack.extend(self.stack.pop()[::-1])
return False
面試官追問「為什麼 next() 是攤還 O(1)」:每個元素最多入堆疊、出堆疊各一次,總操作量與元素數線性相關。記得覆蓋「空巢狀列表」「多層巢狀」用例。
Q2:字母異位詞分組(優於排序)
題目:將字母異位詞分組,要求優於 O(nk log k)(k 為字串最大長度)。
常規解法是排序字串當 key(O(k log k)),但面試官要最佳化。用長度 26 的計數陣列轉 tuple 當 key,每個字串處理是 O(k):
from collections import defaultdict
def group_anagrams(strs):
groups = defaultdict(list)
for s in strs:
count = [0] * 26 # "aab..." -> [2,1,0,...]
for ch in s:
count[ord(ch) - ord('a')] += 1
groups[tuple(count)].append(s) # tuple 可雜湊,當 key
return list(groups.values())
面試官提示「能用質數乘積當 key 嗎」,可以補充:質數乘積可能溢位,計數陣列更安全,也更貼合生產場景。總複雜度 O(nk)。
三、第三輪 HM 面
全程圍繞履歷展開,更關注溝通和成長性。先自我介紹,再挑專案提問,重點問:
- 最有挑戰性的專案(infra / 系統設計選型與落地)。
- 如何與隊友協作。
- 遇到突發情況如何處理——可分享一段實習經歷:因為什麼導致失敗、最後怎麼解決並避免再犯,回答要能「圓回來」,技術細節也要到位。
這輪通常不考 coding,是「正常聊天」式,從你的表達決定是否合適。
四、總結
TikTok SDE NG 三輪:前兩輪純 coding 考思路清晰 + 程式碼完整 + 邊界敏感(陣列貪心、換根 DP、堆疊迭代器、計數 key),第三輪 HM 看溝通與成長。難點不在單題,而在快節奏下兩題連做還要講清複雜度。
FAQ
Q1:TikTok SDE NG 幾輪?
三輪:前兩輪純 coding(每輪兩題,時間緊),第三輪 HM 履歷深挖 + infra/系統設計 + 行為題。
Q2:異位詞分組為什麼不用排序?
排序 key 是 O(k log k),面試官要求優於此。用長度 26 計數陣列轉 tuple 當 key,每串 O(k),總 O(nk),且避免質數乘積溢位風險。
Q3:巢狀迭代器怎麼答得穩?
用堆疊逆序壓入,hasNext() 迴圈展開列表直到堆疊頂是整數,next() 直接彈出。要能解釋「每元素最多進出堆疊各一次」=> 攤還 O(1),並覆蓋空列表與多層巢狀。
Q4:怎麼應對兩題連做的快節奏?
先 clarify 輸入格式再落筆、邊寫邊覆蓋邊界、主動講複雜度。如需 TikTok 快節奏 coding 輪的限時陪練,或 VO代面 / VO輔助 的即時對接,可發崗位 JD 先做題型預測。
正在準備 TikTok 面試?
oavoservice 提供 TikTok SDE 全流程陪練:雙題連做限時模擬、換根 DP/堆疊迭代器/計數 key 等高頻題演練、HM 履歷深挖與 infra 系統設計問答,也支援 VO代面 / VO輔助 的即時對接。教練含前大廠資深工程師,熟悉 TikTok「思路清晰 + 程式碼完整」的評分風格。
立即新增微信 Coding0201,獲取 TikTok 真題與陪練。
聯絡方式
- 微信:Coding0201
- Email:[email protected]
- Telegram:@OAVOProxy