⁣前端面试题-002-二维有序数组合并成一维

781 阅读1分钟

题目

合并二维有序数组,变成一维有序数组,归并排序的思路

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

分析

  1. 大逻辑是把「子数组」两两合并, 并且排好序的,就算是奇数个子数组,最终也合并为一个。
  2. 小逻辑是 两个子数组 合并的具体操作。

实现

小逻辑,实现两个子数组的具体合并排序

/*
  功能: 将两个有序子数组合并为一个
  参数: arr, brr 将要合并的数组
  返回: 结果数组
*/
function merge (arr, brr) {
  const res = [] // 结果数组
  // 其中一个数组长度为0时,就会停止比较排序, 把剩余的元素追加到结果数组尾部
  while(arr.length > 0 && brr.length > 0) {
    if (arr[0] < brr[0]) {
      // 弹出子数组头部元素, 数组长度自然减1, 弹出元素保存至结果数组
      res.push( arr.shift() ) 
    } else {
      res.push( brr.shift() )
    }
  }
  // 把剩余数组无脑追加到结果中,并返回
  return res.concat(arr, brr)
}

大逻辑,实现外层数组两两子数组合并操作

/*
  功能: 处理安排哪两个子组数组合并
  参数: bigArr 要处理的二维有序数组
  返回: 处理好的一维有序数组


  算法过程描述
      const bigArr = [ 子数组A, 子数组B, 子数组C ]
  
  步骤1: 
	取出 子数组A, 子数组B     bigArr变为 [ 子数组C ]
  
  步骤2: 
      中间结果数组 = 合并排序(子数组A, 子数组B)
  
  步骤3:
	中间结果数组 存到 bigArr  bigArr变为 [ 子数组C, 中间结果数组 ]

  重复之前操作, 合并两个数组
      bigArr 变成 [ 最终结果数组 ]
	  
*/

function arrayFlat (bigArr) {
  
  if (bigArr.length === 0) return [] // 数组长度为0, 则直接返回空数组
  
  // 数组长度大于1时循环,等于1时结束
  while(bigArr.length > 1) {
    let sub1 = bigArr.shift()  // 取第0个子数组, 长度减1
    let sub2 = bigArr.shift()  // 取第1个子数组, 长度减1
    let tmpArr = merge(sub1, sub2) // 合并两个子数组为中间临时数组
    bigArr.push(tmpArr) // 中间临时数组压入原来的大数组中
  }
  
  // 数组长度等于1时,返回第一个,也是唯一的元素,即排好序的数组
  return bigArr[0]
}

测试和结果

let xxx = [[2,5,6],[7,9,10],[1,4,8],[3,13],[12,14]]

let result = arrayFlat( xxx )

console.log( result )

2021-06-22_153820.png

也在学习前端的朋友, 可以一起讨论. 个人微信 h2o_9527 / QQ群 929330787