前端面试题-002-二维有序数组变一维

题目

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

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 )

在这里插入图片描述

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水哥澎湃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值