陣列中出現次數超過一半的數字

Novice-XiaoSong發表於2020-12-13

劍指Offer 39 陣列中出現次數超過一半的數字 [easy]
在這裡插入圖片描述

一、題解1

1. 思路:hash字典
  1. hash 字典統計數量,數量大於陣列長度一半時返回結果
2. 時間複雜度:O(n)
3. 空間複雜度:O(n)

二、題解2

1. 思路:排序
  1. 排序
  2. 排序後的中位數一定是的結果
2. 時間複雜度:O(nlogn)
3. 空間複雜度:O(logn) 排序遞迴棧空間
4. 實現
/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    nums.sort((a, b) => a - b);
    return nums[Math.floor(nums.length / 2)];
};

三、題解3

1. 思路:摩爾投票法(Boyer-Moore)
  1. 前提:目標數的數量大於陣列長度的一半
  2. 每一個目標數與其他如何非目標數抵消,最終剩下的一定是目標數
2. 步驟

在這裡插入圖片描述

補充

  • 當votes變為0時,若上一輪假設的眾數是目標數,則其他數與目標數消耗的數量一致,剩下的數字中目標數數量依舊大於一半
  • 若上一輪假設的眾不是目標數,則目標數消耗數量小於其他數,剩下的數字中目標數數量依舊大於一半
3. 時間複雜度:O(n)
4. 空間複雜度:O(1)
5. 實現
/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    // 預處理(無)

    // 摩爾投票法
    let curr = nums[0], vote = 1;
    for(let i=1, len=nums.length; i<len; i++){
        if(vote === 0) curr = nums[i];
        if(nums[i] === curr) vote++;
        else vote--;
    }

    // 返回
    return curr;
};

四、題解4

1. 思路:位運算
  1. 目標數數量大於陣列長度的一半,相應的,該目標數的二進位制數中,每一位(1 / 0)的數量也大於陣列長度的一半

相關文章