leetCode题解——Majority Element

转自:http://www.xgezhang.com/leetcode_majorigy_element.html?utm_source=tuicool


题目描述:

Given an array of size n, find the majority element. The majority element is the element that appears more than⌊ n/2 ⌋times.

You may assume that the array is non-empty and the majority element always exist in the array.

分类:

排序、哈希表、位运算

思路:

这道题解法非常多,自己做的时候只写了一个nlogn的排序的算法,其他算法在后面讨论。

简单来说就是把数据进行排序,然后遍历一遍记录出现次数最多的那个。

代码:

class Solution:
    # @param num, a list of integers
    # @return an integer
    def majorityElement(self, num):
        num.sort()
        length = len(num)
        currNum = num[0]
        times = 1
        for i in range(1,length):
            if (num[i]==currNum) :
                times = times+1
                if (times>=length/2+1 ): return currNum
            else:
                currNum = num[i]
                times = 1
        return currNum

进一步思考:

这道题有没有O(n)的解法呢,答案当然是有的,而且不止一个:

1.哈希表:思路也比较清晰,就是通过哈希表来存储,然后再查找哈希表中出现最多的元素,代码略。

2.位运算:这个方法是看了Solution之后才知道的,这里假设数据值范围为(1,2^32-1),那么我们需要一个32个元素的list,初始值都为0。这里的32表示元素转换成二进制之后的32位数。对于每一位数,遍历数据list里的所有数,记录该位为1的个数。如果个数>=len(num)/2+1,则该位为1,否则为0。同理算出每一位,再转换成10进制数即为出现次数最多的数。

3.随机采样算法:因为题目中告诉了这个数一定会出现,而且出现的次数>=1/2,那么我们可以随机取一个数进行判断。理论上平均两次就可以找到这个数。当然从算法的角度上来看这个算法的最坏情况是infinite(考虑永远都取不到正确数的情况),但对于一个实际问题这个方法还是可行的。

4.moore’s voting 算法:这个算法以前没有听说过,是专门解决这一问题的,给一个链接让大家参考一下:http://http://www.cs.utexas.edu/~moore/best-ideas/mjrty/

具体证明在链接里面也能找得到,内容有点多我也没有细看,有兴趣的朋友可以看看,这里附下代码:

class Solution:
    # @param num, a list of integers
    # @return an integer
    def majorityElement(self, num):
        currNum = -1
        times = 0
        for i in range(len(num)):
            if (times == 0):    
                currNum = num[i]
                times = 1
            else:
                if (num[i]==currNum):
                    times = times+1
                else:
                    times = times-1
        return currNum

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值