好友抖音面试
前段时间,好朋友Hellovass参加抖音的面试(高级Android开发工程师)。按照字节的惯例,手撸算法是跑不了的。首先在这里祝好朋友在抖音一切顺利,事事顺心。
题目
终于有心思静下心来搞点事情了,第一件事就是先回顾下好友的面试真题:LeetCode第297题——《二叉树的序列化与反序列化》。
这是一道难度为Hard的题目,其实如果熟悉二叉树的BFS和DFS的话,思路应该会是比较水到渠成的。
题目分析
回到这个题目,题意是你怎么把二叉树变成”一串字符串”,然后又怎么通过字符串重组回一颗二叉树。首先要序列化一颗二叉树,首先肯定要遍历树的各个节点吧:有DFS(深度优先遍历)和BFS(广度优先遍历)。这个题我最开始的想法就是BFS,因为递归是比较抽象的(本人水平有限,所以就抽象了),所以我不会第一时间就往递归上面去想。
假设一棵树:
1 | 2 |
BFS的结果是:
1 | 2,1,3 |
由 2,1,3 怎么重建二叉树呢,不难发现,我们先把根节点2拿出去,剩下的1和3就分别是2的左右孩子了。
假设这棵树再大一点:(题目那颗)
1 | 1 |
BFS的结果是:
1 | 1,2,3,4,5 |
根据上面的思想,先把root节点拿出来,取后面的两个分别作为左右孩子:
1 | 1 |
这里没问题,继续为2找左右孩子,这时候就取到4,5了,变成:
1 | 1 |
这里显然就不对了。其实题目已经给了tips:
用上面的思想,按照:
1 | 1,2,3,null,null,4,5 |
来重建二叉树,就没有问题了。
那么思路就很清晰了,思路清晰也不代表代码好写,这是两码事;写完代码也不见得所有的test case都能pass。
代码实现
先把序列化的写了,比较传统的BFS,碰到左右子树为空的则输出为nil字符串,这里任意能区分的字符即可。
1 | // Encodes a tree to a single string. |
反序列化的代码,也是要用到一个队列,跟遍历一样,先把root节点放到队列中,然后不断地循环,把需要找左右孩子的节点继续放入到队列中去:(通过代码注释来讲解)
1 | // Decodes your encoded data to tree. |
运行结果
写完放到LeetCode上跑一下看看:
击败数并不高,说明还有更好的写法。但是如果你是面试,其实到这里就已经没有问题了。当然学习不全是为了面试,要不然就真的太累了,希望大家都能找到个好公司,节日福利多多的那种。
谢绝转载
【Happyjava】原创文章,未经允许,谢绝转载!