每日一算--求眾數

流浪的先知發表於2019-04-11

題目

給定一個大小為 n 的陣列,找到其中的眾數。眾數是指在陣列中出現次數大於 ⌊ n/2 ⌋ 的元素。 你可以假設陣列是非空的,並且給定的陣列總是存在眾數。

示例

輸入: [3,2,3]
輸出: 3
複製程式碼

示例

輸入: [2,2,1,1,1,2,2]
輸出: 2
複製程式碼

日常找規律

瞬間想到的解法可能就是:

  • 利用物件進行儲存出現的次數,很棒
  • 不太容易想到的就是摩爾投票法跟前後PK

實現方式

hashMap實現

  • 時間複雜度 O(n)
  • 空間複雜度 O(n)
function majorityElement(arr) {
  const hash = {}
  const half = Math.ceil(arr.length / 2)
  for (let i = 0; i < arr.length; i++) {
    if (!hash[arr[i]]) {
      hash[arr[i]] = 0
    }
    hash[arr[i]]++
    if ( hash[arr[i]] >= half) {
      return arr[i]
    }
  }
}
複製程式碼

摩爾投票法

時間複雜度 O(n) 空間複雜度 O(1)

function majorityElement(arr) {
  let count = 0
  let majority = 0
  for (let i = 0; i < arr.length; i++) {
    if ( count === 0 ) {
      count++
      majority = arr[i]
    } else if (majority == arr[i]){
      count++
    } else {
      count--
    }
  }
  return majority  
}
複製程式碼

前後PK法

  • 原理,取陣列前後的一個數進行PK,只要不相等就刪除,這樣一對一PK後,剩餘的的那個數就一定是眾數
  • 時間複雜度 O(n/2)
  • 空間複雜度 O(1)
function majorityElement(arr) {
  let i = 0
  let j = arr.length - 1
  let count = 0
  for (;i < j;) {
    if ( arr[i] === arr[j]) {
      i++
      count++
    } else {
      if (count > 0) {
        i++
        count--
      } else {
        i++
        j--
      }
    }
  }
  return arr[i]  
}
複製程式碼

總結

相關文章