疫情
由于原因,面试基本都改成了线上,相比线下,线上更能考核手写代码,毕竟大家都经历过先是牛客网的算法题面试,然后是线下一面,线上面试有效的把这两者整合到了一起,也有了更多考验真实处理部分业务场景下遇到问题的代码能力。
问题
今天偶然看见这个问题,让我想起之前一些面试er的回答,十分有趣。基本上面试十个人十个都是以递归思路解决的,当然大部分是没有解决的(因为写着写着就把自己绕晕了)。
那么就摒弃代码的实现,专注问题的本质,简单地聊聊思路。如果你想看代码实现,请去baidu搜索即可,一大堆。
// transfer
const a = [
{name:'1', value:1, id:1, pid:0},
{name:'2', value:2, id:2, pid:1},
{name:'3', value:3, id:3, pid:2},
]
// into
const b = {
id:1,
name:'1',
value:'1',
children:[
{
id:2,
name:'2',
value:2,
children:[
{
id:3,
name:'3',
value:3,
children:null
}
]
}
]
}
思路
相信大家都遇到过或实际解决过这个问题。很多developer的第一想法就是递归,我也如此 ==> 同样的结构,同样的嵌套,不知道多少层,每层不知道有多少个,肯定是不断的调用同一种实现即递归。
然后我们就开始以递归为基础实现:
- 遍历同层
- 如果没有找到pid相同,就要重新遍历第一层children
- 把遍历项放入pid相同的target的children字段中
- 递归以上
发现好麻烦,并且写了一会就把自己绕进去了,并且以后如果有结构上的扩展,还要在通用的递归逻辑里增添定制化逻辑,那就意味着每一层,每一个都要进行该逻辑的判断组装,那么此刻你还记得你刚才脑子里形成的递归结构么?如果你也十分头疼,那么恭喜你,你已经被递归的黑洞吸了进去。
且不说递归你到底能不能实现,就算实现了,这个时间复杂度你考虑考虑,深层遍历,同层遍历,如果结构有100层呢?这是我们从心智上无法承受的。那么最大的问题就是循环,如果我们只循环一次呢?把时间控制在O(n),这是不是近乎完美了(因为循环是必须的)。
问题的本质: 构建一个父子关系,能够让我们使用这个满足父子关系的结构,并且子结构可以放在父结构的children字段中。想要的结果: 我们需要尽量少的遍历,尽量少的递归,构建出来这组关系。- 放在children中,children字段是个Array,是个Array...bingo!
谜语:如果我改变,能让你改变,你和我的表象不一,但变化相同。如果你想到了,就成功了。
const b = [
{name:'1', value:1, id:1, pid:0, children:[pid=1的item]},
{name:'2', value:2, id:2, pid:1, children:[pid=2的item]},
{name:'3', value:3, id:3, pid:2, children:null},
]
所以,评论区告诉我,谜底是什么?
解决的思路会随着你们的答案放在评论区。