LeetCode169 Majority Element-python(easy)

題目來源:

https://leetcode.com/problems/majority-element/description/

題目分析:

給定一個n維的數組,尋找出現次數最多的那個元素。那個出現最多的元素至少會在數組中出現一半,要我們求出這個元素。

下面有好幾種方法:

1.暴力搜索的方法

  對數組中的元素進行遍歷,然後分別求出每個元素出現的次數,如果該次數大於列表的一半,則輸出這個數字。其具體代碼如下:

class Solution:
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        major_num=len(nums)//2   %python3裏的“/ "表示 浮點數除法,返回浮點結果;" // "表示整數除法
        for num in nums:
            s=sum(1 for elem in nums if elem==num )  %這裏表示的是每次if判斷正確就sum+1
            if (s>major_num):
                return num

結果是時間複雜度超過了。

2.HashMap方法

  Hash算法實際上就是利用Key計算位置的算法,它利用了字典鍵-值對的特性。在這裏我們採用了python內置模塊collections中的Counter類方法。Collections包含了除了dict,set,list,tuple以外的一些特殊的容器類型。具體可參見文檔:http://docs.python.org/2/library/collections.html。下面主要介紹一下我們使用的Counters類。

  Counter類的目的是用來跟蹤值出現的次數。它是一個無序的容器類型,以字典的鍵值對形式存儲,其中元素作爲key,其計數作爲value。計數值可以是任意的Interger(包括0和負數)。Counter類和其他語言的bags或multisets很相似。因此本題的代碼可以寫成:

class Solution:
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        counts=collections.Counter(nums)
       
        return max(counts.keys(),key=counts.get)

爲了更好的理解代碼,我們可以把上述程序改寫爲:

import collections
class Solution:
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        counts=collections.Counter(nums) %從一個可迭代對象(list,tuple,dict,字符串)創建Counter類
        return max(counts.keys(),key=lambda x:counts.get(x))

Counter類的存儲是一個字典,而get方法是字典中用來得到值的。lambda方法定義了一個匿名類,counts.get(x)得到了counts中所有的值,keys代表了counts中所有的鍵,max函數如果有關鍵字key,用法就是按照key來選最大值,而key是get函數,得到的是值,因此最後一句話就返回了值最大的key,也就是出現次數最多的數。

3.排序法

 因爲出現次數最多的數字佔據了整個數組的一半之多,那麼將數組進行排序後,其中間的那個數一定就是我們要找的數字。其代碼爲:

class Solution:
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums.sort()
        return (nums[len(nums)//2])

4.最大投票算法(需要學習的算法)Moore's voting algorithm

  該算法主要用來解決在元素列表中找到出現元素次數最多的元素。具體可以看http://www.cs.utexas.edu/~moore/best-ideas/mjrty/index.html。算法的思想是:每次都找出一對不同的元素,從數組中刪掉,直到數組爲空或只有一種元素。

不難證明,如果存在元素e出現頻率超過半數,那麼數組中最後剩下的就只有e。當然,最後剩下的元素也可能並沒有出現半數以上。比如說數組是[1, 2, 3],最後剩下的3顯然只出現了1次,並不到半數。排除這種false positive情況的方法也很簡單,只要保存下原始數組,最後掃描一遍驗證一下就可以了。

因此該程序爲:

class Solution {
    public int majorityElement(int[] nums) {
        
        int len = nums.length, candidate=nums[0], count=1;
        
        for(int i=1; i<len; i++) {            
            if(nums[i]==candidate)
                count++;
            else {
                count--;
                if(count==0) {
                    candidate=nums[i];
                    count=1;
                }
            }            
        }        
        return candidate;    
    }
}

如果要採用這個算法,題目中出現次數大於列表的一半是必要條件,因爲我們每次在移除時,最壞的情況是每次移除一個出現次數最多的數和一個非目標數,要確保剩下的數爲出現次數最多的數,則需要它大於列表的一半。

  關於這個算法的改進與變形,可以參看:https://blog.csdn.net/huanghanqian/article/details/74188349



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章