【譯】Swift演算法俱樂部-查詢最大/最小值

Andy_Ron發表於2019-03-03

本文是對 Swift Algorithm Club 翻譯的一篇文章。

Swift Algorithm Clubraywenderlich.com網站出品的用Swift實現演算法和資料結構的開源專案,目前在GitHub上有18000+⭐️,我初略統計了一下,大概有一百左右個的演算法和資料結構,基本上常見的都包含了,是iOSer學習演算法和資料結構不錯的資源。

?andyRon/swift-algorithm-club-cn是我對Swift Algorithm Club,邊學習邊翻譯的專案。由於能力有限,如發現錯誤或翻譯不妥,請指正,歡迎pull request。也歡迎有興趣、有時間的小夥伴一起參與翻譯和學習?。當然也歡迎加⭐️,?????。

本文的翻譯原文和程式碼可以檢視?swift-algorithm-club-cn/Select Minimum Maximum


目標:查詢未排序陣列中的最大/最小值。

最大值或最小值

我們有一個通用物件陣列,我們迭代所有物件,跟蹤遇到的最小/最大元素。

例子

假設我們想在未排序列表[8,3,9,4,6]中找到最大值。

選擇第一個數字8,並將其儲存作為目前為止的最大元素。

從列表中選擇下一個數字3,並將其與當前最大值進行比較。 3小於8所以最大值8不會改變。

從列表中選擇下一個數字9,並將其與當前最大值進行比較。 9大於8所以我們儲存9作為最大值。

重複此過程,直到處理完列表中的所有元素。

程式碼

在Swift中的一個簡單實現:

func minimum<T: Comparable>(_ array: [T]) -> T? {
  guard var minimum = array.first else {
    return nil
  }

  for element in array.dropFirst() {
    minimum = element < minimum ? element : minimum
  }
  return minimum
}

func maximum<T: Comparable>(_ array: [T]) -> T? {
  guard var maximum = array.first else {
    return nil
  }

  for element in array.dropFirst() {
    maximum = element > maximum ? element : maximum
  }
  return maximum
}
複製程式碼

將程式碼放在 playground 測試:

let array = [ 8, 3, 9, 4, 6 ]
minimum(array)   // This will return 3
maximum(array)   // This will return 9
複製程式碼

Swift的標準庫

Swift庫已經包含一個叫做SequenceType的擴充套件,它可返回序列中的最小/最大元素。

let array = [ 8, 3, 9, 4, 6 ]
array.minElement()   // This will return 3
array.maxElement()   // This will return 9
複製程式碼
let array = [ 8, 3, 9, 4, 6 ]
//swift3
array.min()   // This will return 3
array.max()   // This will return 9
複製程式碼

最大值和最小值

要同時查詢陣列中包含的最大值和最小值,為了最小化比較次數,我們可以成對比較。

例子

假設我們想要在未排序列表[8,3,9,6,4]中找到最小值和最大值。

選擇第一個數字8,並將其儲存為目前為止的最小和最大值。

因為我們有一個奇數專案,我們從列表中刪除8,留下兩隊[3,9][6,4]

從列表中選擇下一對數字,[3,9]。 在這兩個數字中,3是較小的數字,因此我們將3與當前最小值8進行比較,並將9與當前最大值8進行比較。 3小於8,所以新的最小值是39大於8,所以新的最大值是9

從列表中選擇下一對數字,[6,4]。 這裡,4是較小的一個,所以我們將4與當前最小3進行比較,並將6與當前最大9進行比較。 4大於3,所以最小值不會改變。 6小於9,因此最大值不會改變。

結果是最小值為3,最大值為9

程式碼

在Swift中的一個簡單實現:

func minimumMaximum<T: Comparable>(_ array: [T]) -> (minimum: T, maximum: T)? {
  guard var minimum = array.first else {
    return nil
  }
  var maximum = minimum

  // if `array` has an odd number of items, let `minimum` or `maximum` deal with the leftover
  let start = array.count % 2 // 1 if odd, skipping the first element
  for i in stride(from: start, to: array.count, by: 2) {
    let pair = (array[i], array[i+1])

    if pair.0 > pair.1 {
      if pair.0 > maximum {
        maximum = pair.0
      }
      if pair.1 < minimum {
        minimum = pair.1
      }
    } else {
      if pair.1 > maximum {
        maximum = pair.1
      }
      if pair.0 < minimum {
        minimum = pair.0
      }
    }
  }

  return (minimum, maximum)
}
複製程式碼

在playground測試:

let result = minimumMaximum(array)!
result.minimum   // This will return 3
result.maximum   // This will return 9
複製程式碼

通過成對挑選元素並將其最大值和最小值與當前的最小值和最大值進行比較,我們將每2個元素的比較次數減少到3次。

效能

這些演算法以**O(n)**執行。 將陣列中的每個物件與當前的最小值/最大值進行比較,所花費的時間與陣列長度成比例。

作者:Chris Pilcher
翻譯:Andy Ron
校對:Andy Ron

相關文章