169. Majority Element [easy] (Python)

来源:互联网 发布:台湾人眼中的大陆知乎 编辑:程序博客网 时间:2024/05/10 19:26

题目链接

https://leetcode.com/problems/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.

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

题目翻译

给定一个大小为n的数组,找到其中的“多数元素”。多数元素指的是出现次数超过 ⌊ n/2 ⌋ 次的元素。
假定数组非空,且给定的数组中一定存在多数元素。

思路方法

首先,暴力双循环是一个方法,但复杂度太高不可取。这道题的解法非常多,下面我实现了一些,有兴趣的可以再搜搜别的方法和实现。

附LeetCode解决建议(若图片看不清,请右键图片在新标签页打开查看):
LeetCode解决建议

思路一

(HashTable)遍历数组,用一个字典记录所有出现过的元素及其个数。由于题目说明多数元素一定存在,故当找到某个元素出现次数大于 ⌊ n/2 ⌋ 时即可停止。

代码一

class Solution(object):    def majorityElement(self, nums):        """        :type nums: List[int]        :rtype: int        """        digits = {}        for i in nums:            digits[i] = digits.get(i, 0) + 1            if digits[i] > len(nums)/2:                return i

类似的,也可以考虑用集合这一数据结构。先找出数组中的所有不同的数,相当于“取原数组的集合”的操作,然后判断该集合中的每个数在数组中出现次数是否过半。

代码二

class Solution(object):    def majorityElement(self, nums):        """        :type nums: List[int]        :rtype: int        """        nums_set = set(nums)        for i in nums_set:            if nums.count(i) > len(nums)/2:                return i

思路二

(Sort)先对数组进行排序,因为多数元素一定存在,且个数超过总个数的一半,那么排序后最中间的那个元素一定是多数元素。

代码

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

思路三

(Randomization)这个方法听起来不是很靠谱,平均复杂度O(n),最差复杂度无穷大,但实际运行还是挺稳定的。其方法是,随机抽一个元素,检查是否是多数元素,由于多数元素个数占大半,期望查找次数<2。

代码

class Solution(object):    def majorityElement(self, nums):        """        :type nums: List[int]        :rtype: int        """        import random        while True:            r = random.choice(nums)            if nums.count(r) > len(nums)/2:                return r

思路四

(Divide and Conquer)分治法。每次将数组分成左右两半,在两半中分别找出现次数最多的元素,若找到的两个元素相同则此元素即为所求,否则在整个数组中分别计算这两个元素出现的次数,取较大的那个。

代码

class Solution(object):    def majorityElement(self, nums):        """        :type nums: List[int]        :rtype: int        """        return self.major(nums, 0, len(nums)-1)    def major(self, origin_nums, left, right):        if left == right:            return origin_nums[left]        mid = (left + right) / 2        major_l = self.major(origin_nums, left, mid)        major_r = self.major(origin_nums, mid+1, right)        if major_l == major_r:            return major_l        return major_l if origin_nums[left: right+1].count(major_l) > origin_nums[left: right+1].count(major_r) else major_r

思路五

(Moore Voting Algorithm)该算法的思想是:每次都找出一对不同的元素,从数组中删掉,直到数组为空或只有一种元素。 不难证明,如果存在元素e出现频率超过半数,那么数组中最后剩下的就只有e。

代码

class Solution(object):    def majorityElement(self, nums):        """        :type nums: List[int]        :rtype: int        """        major = count = 0        for i in nums:            if count == 0:                major = i                count = 1            else:                count += 1 if major == i else -1        return major

思路六

(Bit Manipulation)既然存在所谓大量元素,那么倘若我们将所有的数写成二进制,每个数写一行进行位对齐,那么每一位出现最多的0或1就是大量元素在该位的值。基于这个想法,考虑到题目说的是整数(32位),我们可以统计每一位出现次数最多的0或1,组合即得。
需要注意的是,因为Python对于整数的处理太过方便,当LeetCode的测试程序给出负数(即最高位为1的32位整数)时,用Python进行位处理最终得到的却是正数,所以需要对负数做特殊处理。

代码

class Solution(object):    def majorityElement(self, nums):        """        :type nums: List[int]        :rtype: int        """        major = 0        mask = 1        for i in xrange(0, 32):            count = 0            for j in nums:                if j & mask:                    count += 1                    if count > len(nums)/2:                        major |= mask                        break            mask <<= 1        return major if major>>31 == 0 else major - (1<<32)

PS: 新手刷LeetCode,新手写博客,写错了或者写的不清楚还请帮忙指出,谢谢!
转载请注明:http://blog.csdn.net/coder_orz/article/details/51407713

0 0
原创粉丝点击