Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.python
You may assume that the array is non-empty and the majority element always exist in the array.算法
思路:數組
Find k different element, and 「remove」 them as a group, the remaining element must be the element that appears more than ⌊n/k⌋ times. (Detailed explanation is given in comment)markdown
In this problem, k equals to 2.app
Thus we 「remove」 each pair of 2 different elements, and the remaining element that do not have its counterpart is the desired element.
時間複雜度O(n)空間複雜度O(1)的算法呢? 實際上,早在91年就有人專門就這個問題發表了論文,介紹了一種線性時間的算法: Majority Vote Algorithm。經過名字就能夠看出,這個算法是專門用來解決這個問題的。而因爲做者是J Moore (目前是Utexas的計算機系主任),這個算法有時候也會被稱爲Moore’s Voting Algorithm (固然這個Moore並非提出Moore’s Law的那個Gordon Moore)。ui
算法的基本思想很是簡潔: 每次都找出一對不一樣的元素,從數組中刪掉,直到數組爲空或只有一種元素。 不難證實,若是存在元素e出現頻率超過半數,那麼數組中最後剩下的就只有e。固然,最後剩下的元素也可能並無出現半數以上。好比說數組是[1, 2, 3],最後剩下的3顯然只出現了1次,並不到半數。排除這種false positive狀況的方法也很簡單,只要保存下原始數組,最後掃描一遍驗證一下就能夠了。this
如今來分析一下複雜度。刪除元素能夠在常數時間內完成,但找不一樣元素彷佛有點麻煩。實際上,咱們能夠換個角度來想,用一個小trick來從新實現下該算法。spa
在算法執行過程當中,咱們使用常量空間實時記錄一個候選元素c以及其出現次數f(c),c即爲當前階段出現次數超過半數的元素。在遍歷開始以前,該元素c爲空,f(c)=0。而後在遍歷數組A時,.net
若是f(c)爲0,表示當前並無候選元素,也就是說以前的遍歷過程當中並無找到超過半數的元素。那麼,若是超過半數的元素c存在,那麼c在剩下的子數組中,出現次數也必定超過半數。所以咱們能夠將原始問題轉化爲它的子問題。此時c賦值爲當前元素, 同時f(c)=1。 若是當前元素A[i] == c, 那麼f(c) += 1。(沒有找到不一樣元素,只須要把相同元素累計起來) 若是當前元素A[i] != c,那麼f(c) -= 1 (至關於刪除1個c),不對A[i]作任何處理(至關於刪除A[i])
若是遍歷結束以後,f(c)不爲0,那麼再次遍歷一遍數組,記錄c真正出現的頻率,從而驗證c是否真的出現了超過半數。上述算法的時間複雜度爲O(n),而因爲並不須要真的刪除數組元素,咱們也並不須要額外的空間來保存原始數組,空間複雜度爲O(1)。實際上,在Moore大牛的主頁上有針對這個算法的一個演示,感興趣的同窗能夠直接移步觀看。code
這個問題看上去已經完美的解決了。
2、更通常的狀況呢?
那麼,若是咱們想找的並非超過半數的元素,而是出現頻率超過必定頻率的元素都要找出來,是否也存在一個相似的線性時間的算法呢?答案是確定的。實際上,這一類從特定的數據集中找出出現頻率超過某個閾值的元素的問題,有一個形象的名字叫作Iceberg query,或者叫作host list分析。而Richard Karp 老爺子當年就專門寫了一篇論文來討論這種通常性問題的解決方案,而經過下文的介紹,你們也能夠發現,Karp的方案應該也是受到了Moore的算法的啓發。
首先仍是看一下問題的形式化定義吧:
對於一個序列 以及一個在(0,1)之間的實數。假定表示元素的出現頻率,咱們須要找到全部知足的元素。
原帖鏈接:
https://leetcode.com/discuss/19151/solution-computation-space-problem-can-extended-situation
http://m.blog.csdn.net/blog/wenyusuran/40780253
解決方案:
class Solution {
public:
int majorityElement(vector<int>& nums)
{
int size = nums.size();
int vote = 0;
int count = 0;
for(int i = 0;i < size;i++)
{
if(count == 0)
{
vote = nums[i];
count = 1;
}
else
{
if(vote == nums[i])
count++;
else
count--;
}
}
return vote;
}
};
STL解決方案:
int majorityElement(vector<int> &num)
{
map<int, int>count;
for (vector<int>::iterator i = num.begin(); i != num.end();i++)
{
if ( (++count[*i]) > num.size() / 2)
return *i;
}
}
c語言:
int majorityElement(int num[], int n)
{
int cnt = 0, res;
for (int i = 0; i < n; ++i)
{
if (cnt == 0) res = num[i];
if (res == num[i]) ++cnt;
else --cnt;
}
return res;
}
python解決方案:
class Solution:
# @param {integer[]} nums
# @return {integer}
def majorityElement(self, nums):
count = {}
for i in nums:
if i not in count:
count[i] = 0
count[i] += 1
if count[i] > len(nums)/2:
return i