js数组相关面试题

昨天去人人网面试,面试我的小姐姐让我手写一些关于数组操作的代码,我都写出来了,但是面试官应该是不满意我的实现方式,后来经过面试官的提示,又写出了第二种方法,接下来就将这几道面试题整理在下面。

第一题:[1,2,[3,4,[5,6]]]如何转换成[1,2,3,4,5,6]

我一开始的思路很简单,就是定义一个全局变量的空数组,然后定义一个方法,将原数组传递到这个方法中,遍历该数组,判断每一个元素是不是数组类型,如果是数组类型的话就进行递归调用,如果不是数组就将该元素push到新数组中,从而达到面试官的要求,下面看一下我昨天实现的代码。
定义全局变量

let newArr = []

原数组

let arr = [1,2,[3,4,[5,6]]]
arrayConformity(arr){
    for(let i = 0; i < arr.length; i ++){
      if(Array.isArray(arr[i])){
        this.arrayConformity(arr[i])
      }else{
        this.newArr.push(arr[i])
      }
    }
  console.log(this.newArr)
}

对于该方法确实实现了面试官的需求,但是令人不怎么爽的是,这样就会增加全局变量,所以面试官就给了我提示,让我使用局部变量来实现这个需求,思考了半天,思考出了个大概,就是像快速排序的道理一样,当我提到类似快排的原理一样面试官还挺高兴下面我们来看一下第二种局部变量的实现方式。

arrayNewCon(arr){
  let newArr = []
  for(let i = 0; i < arr.length; i ++){
    if(Array.isArray(arr[i])){
      newArr = newArr.concat(this.arrayNewCon(arr[i]))
    }else{
      newArr.push(arr[i])
    }
  }
  return newArr
}

在这里我们使用了concat的方式,类似快排一样,将每次生成的数组作为函数的返回值,然后当递归的时候拿到新的数组和函数的返回值进行concat连接,切记,concat返回的是一个新的数组,所以需要把它赋值给newArr变量,否则会造成数据的丢失,这样减少了全局变量的产生,从代码上看,这种实现比上面的实现好一些。

第二题:要求找出数组中和为target的两个元素并返回

首先我想到的第一种方式是双层循环,遍历,用每一个元素和其他的元素进行相加比较,下面我们来看一下我写的代码

const arr = [1,2,3,4,5,6,7,8,9,9]
getNum(arr){
 let target = 10
 for(let i = 0; i < arr.length-1; i ++){
   for(let j = i + 1; j < arr.length; j ++){
     if(arr[i] + arr[j] === target){
       console.log(`相加为${target}的两个元素是第${i}个元素${arr[i]}和第${j}个元素${arr[j]}`)
     }
   }
 }
}

问题是解决了,既然解决了我们要想一想有没有更优雅的方式来解决这个问题呢?毕竟这种方式是属于暴力查找的方式,而且在外面面试官也是不屑于这种写法的,专业点说,时间复杂度高(咳咳……时间复杂度空间复杂度这一块我了解的并不是很深入,也得加强学习,建议前端的同学们也去看一下数据结构),那么,有没有另一种方式来优雅的解决这个问题,答案是有的,之前面试官给了我一个提示,这个数组是有序的,一开始我并没有明白这句话的含义,难怪我那么菜,后来面试官告诉我了,为什么会提示我这个数组是有序的呢?因为,既然知道这个数组是有序的,那么我们就可以进行两个循环,从左往右遍历,然后从右往左遍历,当两个数的值小于target说明最左侧的值要往后移动,最右侧的值不用动(因为升序数组最右侧的值最大),如果两个数的和大于target需要将最右侧的数据向左移动,以此类推,下面我们用代码来实现以下。

 getNums(arr){
    let target = 10
    if(arr == '' || arr.length == 0){
      return false
    }
    let left = 0
    let right = arr.length - 1
    while (left < right){
      if(arr[left] + arr[right] < target){
        left ++
      }else if(arr[left] + arr[right] > target){
        right --
      }else{
        console.log(`相加为${target}的两个元素是第${left}个元素${arr[left]}和第${right}个元素${arr[right]}`)
        left ++
        right --
      }
    }
  }

如果不是有序数组,那么可以先对数组进行排序,然后再使用该方法。

你可能感兴趣的:(前端面试,js)