🚀手撕大厂常见手写题——数组扁平化

·  阅读 2818
🚀手撕大厂常见手写题——数组扁平化

前言

前不久翻了翻牛客网,看了一些面经,突然就发现,为什么那上面的手写题我咋没几个写的来的?直接被吓出一身冷汗。 😭

于是想到,能不能用一种和原来高考刷题时一样,就对着这些面经刷呢?再加上这段时间的费曼学习法,输出到掘金上,在自己总结学习笔记时,也可以为有需要的朋友们提供一点我的方法。😋

基础

什么是数组扁平化呢?

  • 数组的 扁平化 其实就是将一个多层嵌套的数组转换为只有一层的数组

    比如:将多级嵌套数组 : [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()

}
复制代码

总结

希望能对屏幕前的你有所帮助吧~

❤️❤️❤️

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改