假設有這樣一個需求,一個數組的子元素全是有序數組,相似:算法
let arr= [[1, 2], [0, 3, 4,4,4,6,7,8,9,10], [-1, 4],[-1,3],[-1],[100,200],[5,1000,30000]];
咱們但願將上述數組合併爲一個有序數組,怎麼處理呢?數組
最簡單的方案就是:
將數組總體合併,而後sort排序,代碼以下:性能
let ret=arr.reduce((arr1,arr2)=>arr1.concat(arr2)).sort((a,b)=>a-b); ret=Array.from(new Set(ret)); console.log(ret);
可是上面的代碼沒有充分利用數組子元素自己就是有序數組這一特性,咱們利用「歸併排序」算法,能夠大大的提升相似數組的合併排序性能,代碼(代碼裏面有詳細註釋)以下:code
let arr= [[1, 2], [0, 3, 4,4,4,6,7,8,9,10], [-1, 4],[-1,3],[-1],[100,200],[5,1000,30000]]; // let arr= [[1,2,3]]; function merge(arr){ //記錄每個數組循環比較時的下標變化 function filterIndexArr() { indexArr=indexArr.filter((item,index)=>{ return item.count<arr[item.index].length; }); } //將每次比較的元素放進一個臨時數組裏面,取出最小值放入ret function pushToArr(arr) { let minVal=arr[0].val; let increaseArr=[arr[0].index]; arr.forEach((item,index)=>{ if (minVal>item.val){ minVal=item.val; increaseArr=[item.index]; }else if (minVal==item.val && index!=0){ increaseArr.push(item.index) } }); increaseArr.forEach((item)=>{ let thatItem=item; indexArr.forEach((item)=>{ if (item.index==thatItem){ item.count++; } }); }); filterIndexArr(); ret.push(minVal); } let ret=[]; let indexArr=arr.map((item,index)=>{ return { index, count:0 } }); filterIndexArr(); let compareArr=[]; while (indexArr.length>1){ //循環比較每一個數組的第一個元素 compareArr=indexArr.map((item,index)=>{ return { index:item.index, val:arr[item.index][item.count] } }); pushToArr(compareArr); } //取出最後不須要比較的數組元素,直接拼接到ret後面 let remainArr=arr[indexArr[0].index].slice(indexArr[0].count); ret=ret.concat(remainArr); ret=Array.from(new Set(ret)); return ret; } let ret=merge(arr); console.log(ret);
因爲子數組自己有序,分別記錄要被比較數組的下標,循環取出最小值push到ret就能夠了,是否是很簡單。排序