00:00
好,我们再来看一个递归的题目,那么这个递归的题目呢,要比我们刚才的费波纳切数列呢要来的,呃,更加的有实战意义啊。那么这个题目呢?呃,非常的好,是将数组啊,这个数组是一个高维数组,我们把它加上俩字啊,叫高维数组。好是将呃,一个高维数组或者叫多维数组啊,诶一二,然后里头又是数组对吧,数组里头是三,又是数组四五,然后这是数组6789是吧?哎,那你可以发现这个数组的嵌套情况是非常的复杂,嗯,变成下图所示的对象,咱们现在来看一下这个对象是个什么情况。诶,仔细一看,你就会发现这个对象呢,它有一个属性叫做children。这个Q准属性呢,是个数组。数组的第一项是Y61,不就是Y61吗?然后数组的第二项呢是二,数组的第三项大家注意看,是个对象,这个对象没有Y6属性,对吧,它呢又变成了children准属性。
01:09
啊,Children准属性又是一个数组,数组当中呢,就是Y63,不就是它吗?然后又是children准属性啊,就是Y64Y65,看见没有,那也就是说只要这个像是数,那么这里呢,就是Y6属性啊,这这个对象上是Y6属性啊,只要这里不是数,它又是一个数组,那么这个时候呢,这个对象呢,它就有children准属性,而没有Y6属性。啊,无论这个数多大多小,它都是自己乘一个对象的,你看这个一是单独在一个对象里的,这个二呢,是单独的在一个对象里的,对吧,然后接下来呢,是这个数组是这个children准的属性啊,然后这个就是这个我现在画的红圈,这个数组实际上就是这个345。然后三这不就是三吗?后边这个四五看看,哎,那不就是这个数组吗。啊,所以他就是要么是children啊,要么就是value,要么children要么是value啊,就这样子的下来了,这是一道正儿八经的面试题。
02:08
题目就是这么出的,所以说你现在就要能想清楚啊,能能想清楚就是说他这个题目的要求是什么啊,这个数组的嵌套形式怎么样给它变成这种,呃,不是怎么样,就是要变成什么样。对吧,要变成什么样,这个你要把这个给弄懂,那咱们现在先把这个题目咱们再读读一读啊,那邵老师现在给大家再随便写一个数组,你看比如说现在呢,假如数组是这样123,然后数组诶四五,大家觉得应该变成什么样了,对,就应该变成一个对象,然后是children准属性好第一项是不是一个value啊,哎,因为它就是普通的一个数嘛。所以他就没有Q准属性了,就是Y6属性了。然后这块是二对吧,哎,然后这块呢是三。
03:00
然后最后是四五,这个四五的话,很明显它是数组,所以这块就不是Y6了,而是什么呀,对children啊,我们把字变小,全屏给你们看清楚。好,那这个children的话又是数组,数组里头还有四五啊,四五是不是就是这个value,哎,就要变成这个样子。啊,就要变成这个样子啊,这是四。这是五,哎,那我们等于说又写了一个例子。啊,就说你要知道他这个题目要这么做,这是一道如假包换的面试题,那么邵老师觉得这道题出的特别的好,为什么呢?因为咱们为什么要把这道题给在相关算法储备啊这个小结里头给大家讲解呢?原因很简单,因为这种形式转换的东西啊,实际上在我们view底层啊,很多的地方都用到了啊,很多的地方都用到了,所以这个形式储备的这个东西呢,还是蛮关键的啊,还是蛮关键的,那这种东西咱们刚才说了四个字叫形式转换。
04:02
啊,就从数组的这种形式,嵌套的形式转换成了这种对吧,对象的这种形式转换,那实际上我们就相当于是给它变成啊就是呃需要写,那这道题怎么写,他就需要递归,那为什么需要递归呢?那其实这个递归这件事呢,呃,邵老师给大家总结一个特别特别简单的一个词语啊。特别特别特别简单的一个词语,这个词语你只要掌握它的意思,你就明白什么题目需要啊,用到递归啊,那就是复现啊,那就叫复现。这个题目叫复现,就是什么叫复现呢?规则复现,规则复现什么叫规则复现呢?就是普通的数字。装到Y6里对吧,你看。那么遇见数组了,就装到children里。啊,并且children要给他一个数组。
05:01
那这个数组里头又有数字装到value里,那这个规则是不是复现了?有没有发现,然后再遇见数组了,对吧,再遇见数组了,那就给他装到数组里啊,就在这里给它装到这个数组里。所以你只要记住复线啊,规则复线了,那这个时候呢,就要就要想到用递归啊,就要想到用递归,只要出现了规则复现的情况,所以这个呢,就是一个小技巧啊,就只要出现了规则复现。哎,那么就要想到用递归,所以这是大家面试的时候特别重要的一个事情,那面试的时候,现在很多面试是在线面试啊,不光是因为呃,咱们现在疫情的关系,还有一方面是因为呃,在线面试也可以。就是让面试者用自己的电脑对吧,写一些程序啊,他会在牛客网啊,还有一些网站上去进行,这个牛牛客网大家应该听说过,现在非常火,很多公司都会在牛客网上去进行面试啊,这上面也会有一些笔试的题目,大家也可以找来看一看,对吧?哎,这就是形式转换的一道题目啊。
06:11
好了,那咱们现在呢,就把这道题写一写来,我们把这个,呃,新建一个叫递归深入2.html啊。好,那我们现在呢,就开始去把题目抄一下,那就是转换数组的这样的一个形式啊,比如说现在变成123对吧,然后四五是不是要变为对象啊啊要变为这样的对象,我们把这个对象也抄进去啊。哎,那你说老师你这个你这个注释是不是有点长,没关系啊,注释长就长一点,对吧,这个就是一个题目要变为这样的对象啊,这样的对象。好。那我们这个时候呢,就可以开始写,那写的话,其实这道题目其实还是蛮简单的啊,还是蛮简单的,不难,我们来看一下怎么写啊,然后我们现在就呃把这个呃测试用的数组我们先去写上去啊,12345,咱们先简单一点。
07:09
那这个时候的话呢,我们就需要写程序了,这个程序到底应该怎么写呢?就是你得用心的去把你的意图啊,得想清楚,哎,这是测试数组啊,你的意图是什么呢?你的。作战意图呢,就是我要便利这个东西。对吧,便利这个东西的时候,你会发现就是我,呃当肯定要有一个结果数组啊,我如果便利的这一项是个数字,诶那就简单了,那我现在是不是就直接把一个对象叫VALUE1给他推到这个结果数组中去。对吧,然后再便利便利到另一个数字,然后我就再把Y62给它推到结果数组中去,然后再便利遇见三了,我就再把Y63给它推到结果数组当中去,是吧?这样子来的啊,一个一个变,然后遇见数组的话,你有没有发现刚才我们做的这一切。
08:03
就要重新的再来一遍。发现了吗?就是刚才我们说的做了哪些,咱们重新来啊,就是我现在首先要先准备一个结果数组。好便利,遇见数字了,就把这个V1放进去。便历遇见数字了,就把这个V2装进去,便利遇见三了,就把V3装进去,好,便利遇见数组了,就把刚才经历的这一切再来,刚才经历什么呢?刚才经历了是不是创建一个结果数组,我们一上来是不是就创建一个结果数组,所以你遇见这个数组,又要创建一个结果数组。对吧,然后这个结果数组的话,我是不是要遍历每一项,诶遍历的都是数字,那是不是就是V4,然后是不是就是V5啊,看见没有这样子的,然后这个时候你要把这个结果数组,诶插入到刚才那一层的这个结果数组中,是不是child的啊children children是不是把这个数组给它插插进去。是这样子的一个逻辑。所以那刚才我们说了半天,说到了这个规则浮现,你有没有发现这个规则是仅针对于数组的规则?
09:07
就是遇见数组,我们怎么处理,就是一上来他是个数组,他一上来必然是个数组,因为是数组要进行一个形式转换嘛。所以这个时候我们就可以去写咱们这个转换的这个函数啊,咱们就去写这个转换函数,这个转换函数它的参数是个什么,这个con的这个参数是个什么,比如说这个函数叫扛,它参数是任意项还是数组好一点。大家可以想一想,就它的参数是只接受数组还是任意项?哎,答案很简单,就是数组是非常简单的啊,这个数组是很好想的,就很好想,就数组。就完事了。啊,就是数组,因为是什么意思呢?就是我们什么时候递归,遇见数字的时候不递归,遇见数字的时候不用递归,遇见数字在递归,递归个毛啊对吧?哎,那这个遇见数字了不递归,我们遇见数组了,我们再递归,所以这个时候我们的参数设置为数组是非常简单的。
10:06
啊,然后这个时候你就会发现我们就要准备准备准备一个结果数组,那这个结果数组比如说叫result,好,然后我们现在要便利传入的这个AR的每一项,啊,我们现在要遍历来I等于零,然后I小于A的Les,然后I加加。我们遍历它的时候干嘛?很简单,就是如果你去检测啊,Type of a的第项,它的类型是number的话,那我这个时候是不是直接往结果数组中去push一个value这一个数就行了。发现了吗?就是你便利到的这一项是数字,非常简单,直接往里头放就行啊,也就是说如果遍历到的数字是number,那么直接放进去好。啊,直接放进去,然后那同学就知道了,Else if就是如果是数组,那么就是递归,我们先不不着急啊,我们先测一下现在的情况,返回result,然后我现在玩一个O,就等于convert一个A,我们输出这个O。
11:10
好,刷新。那这个时候你就会发现Y6123啊,这个跟题目要求是正确的啊,完全正确的,但是现在呢,你会发现这个四五没在里头,对吧,四五是不是这要加l if呀,就如果便利到的这项是数组,数组要用ara isra来进行检查啊,就是如果便利到的这项是数组,如果便历到的这项是数组。哎,那么就递归,怎么递归呢?是不是要往当前的这一层的结果数组当中推入一个children啊,然后这个children来自于什么?对,来自于递归。对吧,我convert这个AR的Di项不就行了吗?ARD项是个数组啊,因为我们这检查了,然后你放入convert这个函数,Convert函数呢,就又会执行一遍,又会执行的时候呢,它就会返回result result是什么?是数组啊,那言外之意不就是遇见一个数组,它就会将当前层的result结果数字当中推入一个children准也是个数组吗?
12:11
对不对,一个字妙啊,兄弟们可以把妙这个字打到弹幕上啊。对吧,它就这个就是一个形式转换的递归,那这个就对了,咱们刷新看一下它就对了,没有错误的道理啊,Y6123,这是个数组,长度是二,Children准长度是二嘛,然后children准展开之后又是Y64 Y645嘛,你这可以随便的变身没问题,比如说四五,然后我们在这再来一个六。啊,然后再来一个数字啊,或者再来一个数字,再来一个数字七啊八九,看见没有,这样咱们极端一点啊,然后这块再来个十逗号,再来个11,你看极端一点,这完全没问题啊,咱们对着看啊,对着这个对着这个结果咱们最小化看一下。好,咱先看最外层,最外层是不是1233个数,然后是两个children准,没问题吧,这是两个children准,然后11。
13:01
对吧,咱们先看这复杂的children吧,啊,先看这四五,这children准啊,这简单,这里头就四五啊,好,然后再看这复杂的children,复杂的children展开之后长度是三。看见没有,是不是六一个数组十没问题吧,哎,然后这个数组长度是二,为什么长度是二,因为这个这个数组长度是二,就这个蓝颜色的啊,因为这里有个黄数组和九嘛,所以展开之后,你看是不是一个黄数组和九。啊,然后这个数组展开呢,又是一个数组,哎,和一个八,这个数组展开之后,它里头只有一个七,这个答案是对的。看见没有这个形式转换程序就对了,所以这块接收是个数组啊。哎,接收是个数组,是这样子做的啊,没有什么毛病,那么还有一种写法啊,就是这是第一种就是递归的写法啊,这是转换函数啊,这是写法一,我们把它可以给注释一下,注释掉啊。还有第二种写法啊,第二种写法如果我写出来的话,你会觉得比第一种写法呢,可能还要妙啊,还有第二种写法,咱们来看一下啊,第二种写法呢,就是转换函数啊,写法二,写法二的话呢,就是刚才老师说的一件事就是。
14:12
我可以怎么着对,我是不是可以这么想,就是。嗯,如果我便利到了这项,它是个数组的话,那数组的话不就需要去递归吗?那递归的话是不是就相当于我现在要去把它的里头的每一项啊,你想想递归是什么意思。递归的话,不就又要便利它里头每一项吗?对吧,那又要便利里头每一项的话,那我想问问大家,比如说原数组有几项,你递归出来的项是不是一定长度是几。就是原数组,比如说现在有几项原数组,现在有一项,两项,三项,四项,是不是四项啊,当然这个算一项,所以长度是四,所以你递归出来的那个children,大家琢磨琢磨,你递归出来的那个children是不是它一定是。长度为四的。
15:01
对吧,那我在偷偷的暗示你什么俩字映射。啊,我在偷偷的暗示你两个字映射。Map,对,是我们ES6当中的数组方法映射。就是他会有一种映射的感觉在。大家发现了吗?就映射的感觉在,所以这个时候你就会发现我我我我不用写for了,就我一会再写个转换方法二,它会特别的好看,就是根本就不需要出现fair这个单词啊,也不出现while这个单词,就是你感觉他根本没有。没有循环。啊,就是它真的是非常的神奇,就是算法这个东西越写越漂亮,所以转换二,那这个时候呢,这种写法的话,大家要注意啊,它就有一个问题了,他这个问题呢,就是你要用这种写法的话,它这个参数呢,就不能用arr来当了。啊,这个时候为什么不能用AR来当了,因为你如果这个时候它的参数只是AR,那么他面对啊,他面对普通值的时候,他就没有那个返回值了。
16:08
能明白吗?哎,它就没有返回值了,他就特别。呃,不好控制,所以这个时候我们就用item,就相当于这个参数呢,不是A,就是参数,不是AR这个这个词语,而是item就意味着现在啊,Item可能啊,可能是数组,也可能是数字。那为什么这么写呢?这个就是一个编程经验,就我会这么判断,你看啊,就是我们还是会判断,就如果。啊,你的type of item,好,你传进来的是number,那我就直接返回一个对象。注意看我是不是直接返回一个对象item呀。你看我这么写,就是如果你传进来的这个像啊,传进来的参数是数字,那我就直接返回一个对象,Value item,那这句话跟刚才那句话感觉相同,其实不相同,为什么有两点不相同?第一,刚才这句话是不是循环便利了?
17:06
看见没有,就刚才的这个啊,算法它循环便利了。发现了吗?它循环便利了啊,它循环这个for用for,这是第一点不同,第二个不同是它准备第一刚才那种准备的一个结果数组。发现了吗?他准备这个结果数组,然后我们往结果数组中推入VALUE6ARI,但是这种写法当中,你发没发现我们没有准备结果数组,我们直接返回value item。对吧,所以这块,那你现在肯定二战和尚摸不到头脑,说老师这什么意思呀,对吧,那那他什么意思,是不是就是我我要把一个8CON味的转给O,那O是不是就成为你看刷新确实O就变成Y68了,没错。那你说老师人家给你的是数组啊。对吧,那别着急啊,我还没写完呢,Else if are瑞,哎,意思are瑞,注意看啊,那你说老师你刚才吹牛啊,就说如果传进来的参数啊,咱们写一下这如果传进来的参数是数组。
18:03
对吧?哎,这是如果传进来它就是数字啊,那你说老师你刚才吹牛了,说老师你你说你这个案例中不用写for,不用写循环语句,也不用写结果数组,我说我没吹牛,咱们看一下啊,注意看啊,我们这个时候干嘛,如果传下来的是数组,那我现在是不是要给他组建成children准属性,然后把这个数组映射出来呀。对吧?啊,但映射其实里头暗含了循环,就是它里头暗含了for,自带了for,所以老师这里是使了一个炸,用map替代了循环。对吧,那这里的每一项怎么办?这里的每一项当然要用下滑下来它们当做它的循环变量,因为不能跟这个重名啊,那对这里的每一项递归,是不是这里的每一项递归就可以了。所以有没有发现这种写法更美?啊,你看刚才这种写法,咱们写了多少遍多少行,一行,两行,三行,四行,五行,六行,七行,八九十,11 12,十三十四十五十五行,那这个呢,一二三四五六七八九十十一少五行。
19:09
并且少了个循环语句,少了一个Y那个结果数组。啊,我们就遇见你传入的这一项是数组,那我就返回一个children准的映射就行了,那你看咱们盘一下代码,我一进来是不是就是个数组,所以一进来这个衣服不匹配,进到else里了,它就会映射呀。对吧,然后这个时候他就开始映射这个数组的每一项嘛,一映射这个数组每一项,这一项是不是普通数字,普通数字就返回Y62,然后普通数字,普通数字这一项是不是又要映射。是不是就叫映射,然后一映射的话,每一项又要递归。看见了吗?所以这种写法二的话,你会发现递归次数是要比刚才这个递归次数多的,因为刚才这一次的话,它是只有遇见数组的情况下才递归。对吧,遇见数组的情况下才递归,而写法二是不是遇见任何项都递归。对吧,哎,也就是说写法一及写法一是呃,写法一的递归次数啊,要大大哎要大大小于此写法二写法二。
20:12
哎,写法二因为因为什么,因为这个写法二中啊,就是遇见什么东西,哎,都要递归一下啊,都要递归一下,但是遇见普通值的话,他递归一下它上,它不就也就返回这个了吗。对吧,那但是尚老师要跟大家说一句啊,咱们先看结果啊,忘了忘了看结果了,刷新结果是对的啊,123,然后children准你看这个不是四五吗。对吧,结果是对的,然后你再复杂一点,比如说12345,然后再嗯,方括号,方括号方括号,然后六方块789,对,再来个十啊,这是对的啊,刷新没问题啊,这个代码是能经得住考验的,不可能给大家一个错的,你看这个十是单独的吧,没问题,然后这是长度为二,这个长度为二十四五,这里头没错吧,哎,然后这个长度也为二,里头是蓝颜色的,这个678和这个九嘛。
21:03
啊,不是展开,你看这是九单独的发现了吗?然后这个里头是那个啊。七八十单独的嘛,对吧,没有任何问题。啊,所以算法肯定是对的,但是呢,咱们要告诉大家这种写法二是更值得学习的。啊,为什么更值得学习,因为咱们形式上看,你就会觉得这种写法二的这种形式实际上就会给咱们别说别的,不说虚的啊,咱们就说个大实话,就说会给面试官带来更大的一个就是呃,让这个就让你让你感觉到你更牛是吧?哎,让你感觉到更牛啊,就这个人能用最简单的一些代码就能把这个算法给实现了啊,用最简单代码就能把这个东西给实现了,然后面试官呢,其实是挺喜欢这样子的求职者的。对吧?诶,每一项我都递归,就遇见的每一项我都递归,但是你递归的时候如果遇见的是数字,那它就会返回这个东西,也就是说你把这一项交给下一次递归来决定,而不是你这一次递归的时候辛辛苦苦的判断什么push什么什么的发现了吗?对吧?然后你也不用显著的准备结果数组为什么不用显著?因为你这一次的返回的就children准的这个数组,Map不是映射吗?映射也会在内存中开辟新数组啊。
22:15
他就暗含了。好吧,哎,所以这里给大家讲了两种方法,希望这两种方法呢,大家都能多写几遍啊,写法一多写几遍,然后重点研究研究写法二,写法一可能好多同学会,但是写法二呢,可能不是特别的会,但没关系,老师讲完之后呢,就都应该会了啊。
我来说两句