JS面试题之——数组转置与螺旋矩阵

JavaScript016

JS面试题之——数组转置与螺旋矩阵,第1张

输入 :一个二维数组,例如:

    [ [1,2,3] , [4,5,6] , [7,8,9] ]

输出 :二维数组的转置

    [ [1,4,7] , [2,5,8] , [3,6,9] ]

    矩阵的转置就是行列互换

function arrayT(sArray){

    var tArray = []

    //对目标数组初始化

    for(var i = 0i <sArray[0].lengthi++){

        tArray[i] = []

    }

    //转置数组

    for(var i = 0i <sArray.lengthi++){

        for(var j = 0j <sArray[i].lengthj++){

            tArray[j][i] = sArray[i][j]

        }

    }

    return tArray

}

注:

    这是一道本人经历的面试题,题目要求是给一个字符串,"abc def ghi",输出为"adg beh cfi"。

    通过这个面试题,我想到了数组的转置操作。

该题是在数组转置的基础上,我想到了之前leetcode上的一道题目,就重温一下。

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

输入:

[

    [ 1 , 2 , 3 ] ,

    [ 4 , 5 , 6 ] ,

    [ 7 , 8 , 9 ]

]

输出:

[ 1 , 2 , 3 , 6 , 9 , 8 , 7 , 4 , 5]

其实是相当于每次遍历完外圈,然后遍历内圈;

我们可以把遍历每一圈作为一个完整的事件,然后不断去重复遍历每一圈就可以解决这个问题。

其实就是递归的运用。

arr =>{

    // map函数用来完成当前矩阵最外一圈的遍历

    // 二维数组 arr 表示当前矩阵

    // 一维数组 result 用来保存遍历结果 

    let map = (arr, result) =>{

        // 矩阵的高度即行数

        let n = arr.length

        // 遍历矩阵的每一行

        for(let i = 0i <ni++){

            // 若第一行 按顺序插入

            if(i === 0){

                result = result.concat(arr[i])

            } else if (i === n-1){

                // 若最后一行 倒序插入

                result = result.concat(arr[i].reverse())

            } else {

                // 若中间行 插入该行最后一个元素 并将该元素从矩阵中删除

                result.push(arr[i].pop())

            }

        }

        // 将已经遍历的第一行和最后一行从矩阵中删除

        arr.pop()

        arr.shift()

        // 遍历插入最左侧一列 此时删除首位两行后矩阵高度已变为n-2

        for(let j = n - 3j >= 0j--){

            // 避免arr[j]长度为空时插入undefined

            if(arr[j].length){

                result.push(arr[j].shift())

            }

        }

        // 截止条件 矩阵有元素就继续递归

        if(arr.length){

            // 把已将遍历元素删除的矩阵进行递归

            return map(arr, result)

        }else{

            return result

        }

    }

    // 将初始矩阵传入, 保存结果的数组初始为空

    return map(arr, [])

}

1.eventLoop

2.setTimeout 误差原因

3.深浅拷贝

4.跨域原因及解决方案

5.css放在头部,js放在尾部

6.css触发bfc

7.webpack plugin和loader区别

8.前端优化

9.协商缓存

10.长列表优化

11.webview交互

12.vue响应式原理

13.原型

14.算法题:数组中有n个元素,排列

EventLoop是计算机系统的运行机制,js就是运行这个机制,因为js是单线程语言,所以一旦遇到一个耗时很长的任务就会卡住,js为了解决这个问题就有了EventLoop

Event Loop是一个程序结构,用于等待和发送消息和事件。

就是在程序中有了两个线程,一个负责应用本身,主线程,另一个负责主线程和其它进程,称为EventLoop

1、js是单线程语言

基本数据类型存放在栈中的简单数据段

引用数据类型存放在堆中的对象

因为定时器是宏任务,如果执行栈的时间大于定时器花费的时间,那么定时器的回调在 宏任务(macrotask) 里,来不及去调用,所有这个时间会有误差。所以就会有误差

宏任务是宿主发起的比如script,setTimeout

css放在头部是因为页面加载html生成dom树的时候就可以同时对dom树进行渲染,防止闪跳,白屏

js放在尾部是因为js会修改dom树,需要一个稳定的dom树

BFC是css的一个布局概念,块级格式化上下文

浮动float不为none的时候

定位为position:absolute和fixed的

display的时候

overflow不为visible

解决浮动父元素坍塌问题

解决自适应布局的问题

解决外边距垂直方向重合问题

loader是文件加载器,运行在nodejs中,并对文件进行打包,压缩转换

plugin是插件,用于拓展webpack的功能

浅拷贝有两种定于,第一种是赋值,第二种是拷贝对象的第一层属性,深层还是一样的

深拷贝是指将对象拷贝一份,无论如何修改都不会改变原有的

响应式原理就是当数据发生改变的时候视图也会跟着更新

VUE是利用了Object.defineProperty的方法里面的setter 与getter方法的观察者模式来实现。