有序陣列的連線問題

2022-03-25 05:47:19 字數 1430 閱讀 9021

1.前言

昨天碰到一道關於如何解決有序陣列的連線問題,這是乙個很常見的問題。但是這裡要考慮到**的效率問題,因為要連線的陣列都是有序的,這是乙個非常重要的前提條件。

2.簡單但效率不高的演算法

我首先想到的是使用內建的concat方法,然後再對其進行排序,這種方法完全沒有考慮到陣列是有序的前提條件,**如下:

function concatsort(arra,arrb)

這裡),大概意思是當陣列的長度較短的時候使用的是插入排序(insertionsort),當陣列的長度較長的時候使用的是快速排序(quicksort)。糾正了自己長時間來的乙個誤區,一直以為sort使用的是冒泡。

3. 取小值插入的方法

大概思路:就是同時對兩個陣列進行遍歷,設定兩個標誌(i,j)用於記錄遍歷的位置,將兩個陣列中較小的那個值插入新陣列中,接著再將標誌往前移動乙個位置,重複比較,直到搜尋值都插入到陣列中。第一次做的時候判斷條件寫錯了,所以出現了死迴圈,暴露了自己演算法能力還是挺薄弱的。

function mergearr(arra,arrb)else

}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進行效能對比,發現第二種演算法的效率明顯優於第一種。不相信就猛擊這裡。

4.問題公升級:增加合併陣列的數量

假如增加陣列的個數,;例如 a = [1,5],b = [2,6],c = [3,4].......k = [....],求合併的陣列。    

悔恨當初沒學好資料結構,最後選擇放棄。面試完後想了想,摳出這麼乙個方法,**如下:   

function mergesort()

return result;

}function mergearr(arra,arrb)else

}return result;

}var a = [1,4,7], b = [2,5,8], c = [3,6,9,10];

console.log(mergesort(a,b,c)); // [1,2,3,4,5,6,7,8,9,10]

5、上述4演算法的改進

上述4的演算法需要合併很多次,也就是需要執行mergearr()的次數為n-1次,其中n為待合併陣列的個數,這樣的效率實在是不敢恭維。那就加速合併的速度,受2路歸併演算法的啟發,將**調整如下:

function mergesort(arr)

for(i=0; i= lenb || arra[i] < arrb[j]))else

}return result;

}

將4、5用到的演算法在jsperf上進行測試,發現效率提高了不少,猛擊這裡看結果:這裡

有序陣列旋轉的問題

一般情況下我們的第一反應肯定是遍歷此陣列,但這肯定不是我們所期望的,因為此陣列是有序陣列旋轉而成,所以我們此時應該想到用二分法來尋找陣列中的最小值。假設我們給定遞增陣列 旋轉後的陣列有下面幾種形式 通過觀察可以發現,在經過旋轉後的陣列在尋找最小值的過程中0的前面的數總是大於0後面的數,所以我們可以以...

合併有序陣列問題

有這樣乙個問題,現在有兩個有序的陣列,第乙個陣列的空間足夠容納兩個有序陣列中的數,利用高效的方法把兩個陣列合併,並使得陣列是有序的,且最後得到的是第乙個陣列,同時不借助其他額外的儲存空間。其實這種題的解法幾乎都是一樣的,都是從最後乙個數開始,這就是取極值的思想,因為陣列是有序的,所以,每個陣列中最大...

有序陣列的合併

includeusing namespace std define size 1024 1 如果可以申請輔助空間,那麼從前從後倒是沒什麼所謂吧,這就像是歸併的一次歸併了。void merge 1 int arr,int lenarr,int brr,int lenbrr while low1 len...