前言
前不久翻了翻牛客网,看了一些面经,突然就发现,为什么那上面的手写题我咋没几个写的来的?直接被吓出一身冷汗。 😭
于是想到,能不能用一种和原来高考刷题时一样,就对着这些面经刷呢?再加上这段时间的费曼学习法,输出到掘金上,在自己总结学习笔记时,也可以为有需要的朋友们提供一点我的方法。😋
基础
什么是数组扁平化呢?
- 数组的 扁平化 其实就是将一个多层嵌套的数组转换为只有一层的数组
比如:将多级嵌套数组 :
[1, [2, [3, [4, 5]]]]
将其扁平化处理 输出:[1,2,3,4,5,6]
ES6有自带的方法flat
- flat(depth) 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
depth
(可选) 指定要提取嵌套数组的结构深度,默认值为 1
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2));
// [0, 1, 2, Array [3, 4]]
// 使用 `Infinity`,可展开任意深度的嵌套数组
const arr = [1, [2, [3, [4, 5]]]]
console.log(arr.flat(Infinity));
// [ 1, 2, 3, 4, 5 ]
复制代码
面试官:手写一个数组扁平化吧
首先,我们肯定也会自己思考,如何实现将多维数组转换为一维数组呢?
简单来说,也就是如何将两个[]
变成一个[]
呢?
[ [ ] , ] => [ ]
[ [ ] ,[ ] ] => [ [ ] ]
这就要考验我们对数组api的掌握程度了
concat()
: 方法用于合并两个或多个数组const array1 = ['a', 'b', 'c']; const array2 = ['d', 'e', 'f']; const array3 = array1.concat(array2); console.log(array3); // ["a", "b", "c", "d", "e", "f"] 复制代码
扩展运算符
:使用扩展运算符使得可以"展开"这个数组,从而消除了最外层的[]
const arr = [1, [2, [3, [4, 5]]]]
console.log(...arr);
// 1 [ 2, [ 3, [ 4, 5 ] ] ]
复制代码
最简单的扁平化
1. 要对一个数组进行合并数组的操作,在原先的数组上操作肯定很困难,所以我们要创建一个数组
并且返回
出来。
function myFlat(arr) {
let result = [];
return result
}
复制代码
2. 因为要进行数组的合并,我们肯定要对数组中的每一个元素进行判断,如果该元素是数组,那么才能进行合并操作是吧~
所以还得判断每一个元素的类型是否为数组
function myFlat(arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
} else {
}
}
return result
}
复制代码
3. 这里就采用我们的concat()
方法进行合并操作了
function myFlat(arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(myFlat(arr[i]));
} else {
result.push(arr[i])
}
}
return result
}
复制代码
那么如何控制扁平化的深度呢?
这里也不用慌,就是在原来的基础上加上一个depth
进行一个深度的控制就好了~
function myFlat(arr,depth){
let result = []
for(let i = 0; i < arr.length;i++){
if(Array.isArray(arr[i]) && depth > 0){
result = result.concat(myFlat(arr[i],depth - 1))
}
else{
result.push(arr[i])
}
}
return result;
}
复制代码
🙅🙅🙅
你以为面试官就问到这里了吗?实际上有些面试官还能找你的麻烦~
能否用非递归的方式实现呢?
这里可以联系到原来我们刷算法时,同样是刷二叉树,一般那种题型都有两种解法,一个递归,一个堆栈。
我们这道题也不例外
使用堆栈
~
1. 创建一个数组并返回,同时创建栈结构
const myFlat = (arr) => {
let res = [];
let stack = [...arr];
return res
}
复制代码
2. 遍历栈中的每一个元素,如果该元素是数组,则用拓展运算符(...)
实现数组的合并
const myFlat = (arr) => {
let res = [];
let stack = [...arr];
while (stack.length) {
let next = stack.pop()
if (Array.isArray(next)) {
stack.push(...next)
} else {
}
}
return res
}
复制代码
3. 最后我们会得到合并完之后的栈,所以这个时候我们还要让栈中的元素一个个出栈,用我们创建的数组
去接住。再按倒序
返回就是我们想要的答案了
const myFlat = (arr) => {
let res = [];
let stack = [...arr];
while (stack.length) {
let next = stack.pop()
if (Array.isArray(next)) {
stack.push(...next)
} else {
res.push(next)
}
}
return res.reverse()
}
复制代码
总结
希望能对屏幕前的你有所帮助吧~
❤️❤️❤️