我在北美家中的书桌前通过视频通道与tiktok面试官在hackrank上连线。题目就出现在了hackrank平台上:
“Given the root of a binary tree, return the most frequent subtree sum. If there is a tie, return all values with the highest frequency in any order. The subtree sum of a node is defined as the sum of all node values in the subtree rooted at that node (including itself).”
中译文:给定一棵二叉树的根节点,返回出现频率最高的子树和。如果存在并列的最高频率,则可按任意顺序返回所有这些子树和。
“子树和”指以某个节点为根的整棵子树中,所有节点值之和(包括该节点自身)。
首先和面试官确认了可以使用python,用它解算法题不用写类型相对C++等其他语言来说速度会更快,代码量和代码行数也会降低,这是CSOahelp的老师们这样给我建议的。在面试的过程中往往我们要45分钟内解决2道题,速度对于我们来说是非常重要的。
我这次使用了CSOahelp的面试辅助服务,对于太久没刷题的我来说,老师们大大节约了我去复健算法的时间,在面试之前我已经根据老师们的稳定设置好了设备和软硬件,面试辅助的老师在线上全程观察我的面试和面试题,并且实时的在我的ipad上给出提示文本。我已经事先将ipad放在了摄像头的死角。由于过于紧张,我还根据老师的推荐购买了一款AI的眼神接触软件,这样看ipad就不会被发现。
题目虽然我没有看懂,但是CSOahelp的面试辅助上已经出现了若干澄清问题,按照之前的演练,我需要先把问题一一和面试官确认,这样我可以为辅助老师争取更多的时间去写代码。由于我的英语不太好,我还要求了辅助老师帮忙用中文写了一遍注释
我的ipad上出现了以下3个澄清问题,我依次向面试官进行了询问:
- 我们需要⾃⼰define binary tree的结构吗?
- subtree sum就是左边孩⼦以及下⾯所有 或者右边孩⼦以及下⾯所有的node的value的sum是吧
- 可以assume每⼀个node的value就是⼀个integer吗
面试官依次进行了回答:
- 不用,我们在面试环境里已经给出了 TreeNode
的定义,你可以直接用,不需要自己再重写节点结构。
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = rig
- 对,就是把当前节点自身的值,加上它整棵左子树所有节点的值,再加上右子树所有节点的值,这三个部分加起来就是这个节点的子树和。
- 没错,题目里所有节点值都可以当作整型来处理,你不必考虑其他类型。
友好礼貌的沟通完毕之后,已经过去了大概5分钟,此时我再看一眼ipad。给力的辅助老师已经写了慢慢一屏幕的代码,在聊天的过程中还在努力的加中英两种语言的注释,有的中文词汇我的确不懂要怎么用英文说,因为在北美上的学,有些中文词汇都很陌生;所幸老师也写了英文的版本,所以我虽然不太明白,但是也可以照着念。
随后面试官示意我可以开始coding,于是我照着ipad一行行的抄写。由于太久没刷题了,抄的还有些吃力,幸好选择了用python,这样至少不会抄漏括号或者句末的分号。大概ipad上的代码如下,并没有完整的贴上来,只是一个示例供大家参考。
from collections import defaultdict
from typing import Optional, List
class TreeNode:
def __init__(self, val: int = 0, left: 'TreeNode' = None, right: 'TreeNode' = None):
self.val = val
self.left = left
self.right = right
def find_frequent_tree_sum(root: Optional[TreeNode]) -> List[int]:
# 哈希表:记录每种子树和出现的次数
count = defaultdict(int)
# 后序遍历函数:计算子树和
def dfs(node: Optional[TreeNode]) -> int:
if node is None:
return 0 # 空节点贡献 0
# 计算左右子树的和
left_sum = dfs(node.left)
right_sum = dfs(node.right)
# 当前子树和 = 左 + 右 + 当前值
total = left_sum + right_sum + node.val
# 更新频率统计
count[total] += 1
return total
# 从根节点开始 DFS
dfs(root)
if not count:
return []
# 找出最大出现频率
max_freq = max(count.values())
# 收集所有频率等于最大值的子树和
result = [s for s, freq in count.items() if freq == max_freq]
return result
大概花了10分钟我抄完了代码,由于有眼神接触的AI修改实时摄像头画面,所以面试官并没有感觉任何的异常。抄完了之后面试官想让我work through一下,辅助老师这个时候打字提示我“照着注释念”,于是我完整的按照英文注释念了一遍,面试官显得很满意。
最后的阶段面试官让我有什么问题可以问他,这个时候辅助老师给出了若干个适合问的问题放在了屏幕上,同时提醒我不要超时,随便选择几个就好。最后面试官怎么答的我已经不记得了。
收到面试通过的消息之后,我非常感慨,到现在为止其实我还是不太懂这道题问的是什么,但是由于有CSOahelp面试辅助服务,我成功的又向北美大厂迈进了一步。听辅助老师说,前面入职大厂的师兄姐们都混的不错,因为面试真的难度太高了反而入职工作之后工作很简单很容易做,再加上现在有强力AI,其实入职之后的初级岗位真的不难。现在我非常期待在北美开启新的职场生涯。
如果你也在准备Point72、Meta、TikTok等大厂的算法与系统设计面试,却不清楚如何拆题和应对各种边界,欢迎添加微信 csvohelp,即可领取北美面试求职通关秘诀。我们也有代面试,面试辅助,OA代写等服务助您早日上岸~
