1. 程式人生 > 其它 >陣列中出現次數超過一半的數字~

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

讀前福利

問題描述

給一個長度為 n 的陣列,陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列[1,2,3,2,2,2,5,4,2]。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。

示例:

輸入:[1,2,3,2,2,2,5,4,2]

輸出:2

分析問題

雜湊表法

我們最容易想到的方法就是使用雜湊表法,去統計每個數字出現的次數,即可很容易的求出眾數。

def majorityElement(nums):
    #用字典來儲存每個數字出現的次數
    data_count = {}
    for x in nums:
        if x in data_count:
            data_count[x] = data_count[x] + 1
        else:
            data_count[x] = 1
    max_value=0
    max_key=0
    #遍歷字典,取出次數最大的
    #因為題目說給定的陣列一定存在眾數
    #所以最大的次數就是眾數
    for key in data_count:
        value=data_count[key]
        if value>max_value:
            max_value=value
            max_key=key
    return max_key

data=[1,2,3,2,2,2,5,4,2]
print(majorityElement(data))

該演算法的時間複雜度是O(n),空間複雜度也是O(n)。

排序演算法

我們將陣列進行排序,那排序後的陣列的中點一定就是眾數。

def majorityElement(nums):
        #將陣列排序
        nums.sort()
        #返回排序陣列中的中點
        return nums[len(nums) // 2]

data=[1,2,3,2,2,2,5,4,2]
print(majorityElement(data))

Boyer-Moore 投票演算法

這道題最經典的解法是Boyer-Moore 投票演算法。Boyer-Moore 投票演算法的核心思想是票數正負抵消,即遇到眾數時,我們把票數+1,遇到非眾數時,我們把票數-1,則所有的票數和一定是大於0的。

我們假設陣列nums的眾數是x,陣列的長度為n。我們可以很容易的知道,若陣列的前a個數字的票數和為0,那麼剩餘n-a個數字的票數和一定是大於0的,即後n-a個數字的眾數仍然為x。

我們記陣列的首個元素是n1,陣列的眾數是x,遍歷並統計票數。當發生票數和為0時,陣列剩餘元素的眾數一定也是x,這是因為:

  1. 當n1等於x時,抵消的所有數字中,有一半是眾數x。
  2. 當n1不等於x時,抵消的所有數字中,眾數的個人最少為0,最多為一半。

所以,我們在去掉m個字元裡,最多隻去掉了一半的眾數,所以在剩餘的n-m個元素中,x仍然為眾數。利用這個特性,在每次遇到票數和為0時,我們都可以縮小剩餘陣列區間。當遍歷完成時,最後一輪假設的數字即為眾數。

class Solution:
    def majorityElement(self, nums):
        #票數和
        counts=0
        for num in nums:
            #如果票數和為0,我們假設num元素為眾數
            if counts == 0:
                x = num
            #如果是眾數票數+1,否則票數-1
            if num==x:
                counts=counts+1
            else:
                counts=counts-1
        return x

該演算法的時間複雜度是O(n),空間複雜度是O(1)。

最後

送大家幾本比較不錯的演算法書籍~

小爭哥資料結構與演算法
連結:https://pan.baidu.com/s/19Jk_G_-QTnGb3GRyzbENgA

密碼:keis

谷歌大佬LeetCode刷題指南
連結:https://pan.baidu.com/s/1vtRIsVltTxmIioqqkeSS5g

密碼:r3xg

演算法小抄
連結:https://pan.baidu.com/s/1rU_T6GRZ-WmV9QFmnJfCBg

密碼:unh5

更多有趣內容,請掃碼關注一波~