js有序數(shù)組的連接問題
1.前言
昨天碰到一道關(guān)于如何解決有序數(shù)組的連接問題,這是一個很常見的問題。但是這里要考慮到代碼的效率問題,因為要連接的數(shù)組都是有序的,這是一個非常重要的前提條件。
2.簡單但效率不高的算法
我首先想到的是使用內(nèi)置的concat方法,然后再對其進行排序,這種方法完全沒有考慮到數(shù)組是有序的前提條件,代碼如下:
function concatSort(arrA,arrB){
return arrA.concat(arrB).sort();
}
為了弄清楚sort排序到底使用的是什么算法,特地到看了V8引擎的算法(連接),大概意思是當數(shù)組的長度較短的時候使用的是插入排序(InsertionSort),當數(shù)組的長度較長的時候使用的是快速排序(QuickSort)。糾正了自己長時間來的一個誤區(qū),一直以為sort使用的是冒泡。
3. 取小值插入的方法
大概思路:就是同時對兩個數(shù)組進行遍歷,設置兩個標志(i,j)用于記錄遍歷的位置,將兩個數(shù)組中較小的那個值插入新數(shù)組中,接著再將標志往前移動一個位置,重復比較,直到搜索值都插入到數(shù)組中。第一次做的時候判斷條件寫錯了,所以出現(xiàn)了死循環(huán),暴露了自己算法能力還是挺薄弱的。
function con(arrA,arrB){
var i , j , k, lenA = arrA.length, lenB = arrB.length , allLen = lenA + lenB,result = [];
for(i=0,j=0,k =0; k < allLen; k++ ){
if(i < lenA &&(j >= lenB || arrA[i] < arrB[j])){
result.push(arrA[i++]);
}else{
result.push(arrB[j++]);
}
}
return result;
}
var a = [1,2,4], b = [3,5,6,7,10];
console.log(con(a,b)); //[1,2,3,4,5,6,7,10]
將這個算法與上面的方法1,在jsperf進行性能對比,發(fā)現(xiàn)第二種算法的效率明顯優(yōu)于第一種。不相信就猛擊這里。
4.問題升級:增加合并數(shù)組的數(shù)量
假如增加數(shù)組的個數(shù),;例如 A = [1,5],B = [2,6],C = [3,4].......K = [....],求合并的數(shù)組。
當時被問到這個問題,第一感覺就是很像”歸并算法“,但是又一想使用歸并算法是用不上數(shù)組有序這個前提條件的。接著又想到了堆排序、快排序等算法,發(fā)現(xiàn)就是無法很有效地用上數(shù)組有序這個前提條件,最后選擇放棄。面試完后依然沒有思路,想了好久不知道如何高效的解決這個問題??旎厮奚岬臅r候,師弟說了一句”又要過節(jié)了“,”又“字點醒了我,代碼如下:
function conMore(){
var outerArr = [], i ,len = arguments.length , result = [];
for(i = 0 ; i<len; i++){
outerArr.push(arguments[i]);
}
if(result.length === 0){
result = outerArr[0];
}
for(i=1 ;i< len; i++){
result = con(result,outerArr[i]);
}
return result;
}
function con(arrA,arrB){
var i , j , k, lenA = arrA.length, lenB = arrB.length , allLen = lenA + lenB,result = [];
for(i=0,j=0,k =0; k < allLen; k++ ){
if(i < lenA &&(j >= lenB || arrA[i] < arrB[j])){
result.push(arrA[i++]);
}else{
result.push(arrB[j++]);
}
}
return result;
}
var a = [1,4,7], b = [2,5,8], c = [3,6,9,10];
console.log(conMore(a,b,c)); //[1,2,3,4,5,6,7,8,9,10]
再次使用jsperf對代碼的性能進行測試分析,結(jié)果請猛擊這里.
相關(guān)文章
JavaScript中定時控制Throttle、Debounce和Immediate詳解
大家可能都知道JavaScript遵循事件驅(qū)動的編程范例,這意味著一些行為可以激活一些響應,并且這些響應僅在發(fā)生特定的行為時才被激活。這篇文章將給大家詳細介紹JavaScript中的定時控制Throttle、Debounce和Immediate,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-11-11
javascript 中的try catch應用總結(jié)
這篇文章主要介紹了javascript 中的try catch應用總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-04-04
JavaScript動畫實例之粒子文本的實現(xiàn)方法詳解
這篇文章主要介紹了JavaScript動畫實例之粒子文本的實現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07
javascript 使用sleep函數(shù)的常見方法詳解
這篇文章主要介紹了javascript 使用sleep函數(shù)的常見方法,結(jié)合實例形式分析總結(jié)了javascript sleep函數(shù)的功能、常見使用方法與操作注意事項,需要的朋友可以參考下2020-04-04
ES6學習筆記之Set和Map數(shù)據(jù)結(jié)構(gòu)詳解
這篇文章主要介紹了ES6學習筆記之Set和Map數(shù)據(jù)結(jié)構(gòu),結(jié)合實例形式詳細分析了ECMAScript中基本數(shù)據(jù)結(jié)構(gòu)Set和Map的常用屬性與方法的功能、用法及相關(guān)注意事項,需要的朋友可以參考下2017-04-04

