合並兩個有序數組為一個新的有序數組


簡便做法

// log
let arr1 = [1, 2, 3, 4, 5, 6, 7] // m個
let arr2 = [2, 3, 4, 7, 10, 19, 39] // n個
let arr = arr1.concat(arr2)
arr.sort((a, b) => a - b)
console.log(arr.join())

注意這里有個坑...如果只用 arr.sort()不傳入函數的話,是按照 ASCI 碼進行排序的,即

// log
let arr1 = [1, 2, 3, 4, 5, 6, 7] // m個
let arr2 = [2, 3, 4, 7, 10, 19, 39] // n個
let arr = arr1.concat(arr2).sort().join()
console.log(arr)

sort 方法內部使用的排序算法為快速排序選擇排序(小數組),更多細節可以參考深入了解 javascript 的 sort 方法。因此上述簡便做法的時間復雜度為O(n*log(n))O(n^2)

降低時間復雜度的一個算法

考慮到兩個數組是有序的,為了提高性能,考慮如下場景:兩個班級合並為一個班級,同學的名次要發生變更(原先在 A 班第一名的小麗,可能連前三名都進不了)。班主任按照如下步驟進行操作:

  • 每輪兩班選出各自班級排名最靠前的同學進行比較。(數組的第一個)
  • 選出的代表再比較他們的真實成績(數值),成績好的人的名字寫在一個本子上(一個新的數組),並將名字從原班級划掉
  • 若干輪后(不超過 m+n),其中一個班級的學生的名字都被划掉了。
  • 此時再把另外一個班級沒有寫在本子上的同學,依名次寫入到本子上。

將上述算法轉化為代碼,如下所示

/**
 * 合並兩個有序數組為一個新的有序數組
 * 時間復雜度 O(m+n)
 * @param {Array<Number>} arr1
 * @param {Array<Number>} arr2
 */
function joinAndSortTwoSortedArray(arr1, arr2) {
  let arr = []
  let flag1 = 0
  let flag2 = 0
  let len = arr1.length < arr2.length ? arr1.length : arr2.length
  while (arr1.length > 0 && arr2.length > 0) {
    if (arr1[flag1] > arr2[flag2]) {
      arr.push(arr1.shift())
    } else {
      arr.push(arr2.shift())
    }
  }
  arr = arr.concat(arr1, arr2)
  return arr
}
let arr1 = [100, 99, 98, 90, 80, 76, 60, 50]
let arr2 = [92, 89, 80, 70, 49, 39]
let res = joinAndSortTwoSortedArray(arr1, arr2)
// log
console.log(res.join())

這其實是歸並排序的一個核心細節。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM