leetcode 169 Majority Element 冰山查询

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
相关文章
相关标签/搜索