【LeetCode】求眾數(四種方法)

Kanny廣小隸發表於2019-01-21

題目

給定一個大小為 n 的陣列,找到其中的眾數。眾數是指在陣列中出現次數大於 n / 2 n/2 n/2的元素。

你可以假設陣列是非空的,並且給定的陣列總是存在眾數。

示例 1:

輸入: [3,2,3]
輸出: 3

示例 2:

輸入: [2,2,1,1,1,2,2]
輸出: 2

Python解法0(利用numpy)

nums = [2,2,1,1,1,2,2]
import numpy as np
counts = np.bincount(nums)
print(np.argmax(counts))

通常為了簡單起見,在Python中計算眾數我們會簡單的使用numpy庫進行計算。注意np.bincount函式的用法,它會統計0,1,…(注意,是從0開始計數)中的每個元素的個數,然後np.argmax(counts)再統計最大的那個的腳標,也就是眾數。這裡侷限性非常大,要預設原本的list中沒有負數,不然會報錯。而且LeetCode中不能調庫,所以這種方法不可取。


Python解法1(暴力計算)

下面介紹兩種暴力計算的方法,其實本質是一樣的,用了兩重的for迴圈,但這種暴力計算的方法非常慢,在測試的時候很可能在規定的時間內跑不出結果。

1. 直接進行暴力計算

class Solution:
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        majority_count = len(nums)//2
        for num in nums:
            count = sum(1 for elem in nums if elem == num)
            if count > majority_count:
                return num

2. 利用count函式進行計算

class Solution:
    def majorityElement(self, nums):
    	n = len(nums)
		for j in nums:
    		if nums.count(j) > n / 2 : break
		return j

Python解法2(利用字典實現)

這裡我們利用了Python中的字典的方法來進行實現,這裡沒有用到在陣列中出現次數大於 n / 2 n/2 n/2的元素,這個資訊,而是對一般的取眾數都管用。並且速度比前面的方法還要快。

這裡有個小技巧,注意dict.get(key, 0)的用法,其表示獲取key對應的值,若沒有,則用0來填補,這裡非常巧妙。

另外則是:max(dict, key=dict.get)表示取其中最大的值(這個是上網查到的),然後,發現。。。在Python3中,max(dict)也是一樣的結果,所以使用後面這個會更加方便。

class Solution:
    def majorityElement(self, nums):
        dict = {}
        for key in nums:
            dict[key] = dict.get(key, 0) + 1
        return max(dict, key=dict.get)

Python解法3(摩爾投票法)

最後這種方法非常巧妙,稱為摩爾投票法。設計出這種方法的真的是一個天才,其時間複雜度為 O ( n ) O(n) O(n)。充分利用了在陣列中出現次數大於 n / 2 n/2 n/2的元素這一條件。摩爾投票法是這幾種方法中最快的。

具體的思想:從第一個數開始,先令count=1,遇到相同的就加1,遇到不同的就減1,減到0就重新換下個數開始計數,到最後是哪個數,那麼那個數就是眾數。

到這裡肯定有人和我一樣的疑問,假設有個數是眾數,它在開始和結尾,結果在中間被一些別的數count了很多次,結尾會不會變不回來,結果當然是不會的!不信。。可以自己試試。

class Solution:
    def majorityElement(self, nums):
		major = nums[0]
		count = 1
		n = len(nums)
		del nums[0]
		for i in nums:
		    if count == 0:
		        count += 1
		        major = i
		    elif major == i:
		        count += 1
		    else:
		        count -= 1
		return major

題目網址:https://leetcode-cn.com/problems/majority-element/

相關文章