您的位置:首页 > 编程语言 > Python开发

169. Majority Element [easy] (Python)

2016-05-14 20:04 981 查看

题目链接

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解决建议(若图片看不清,请右键图片在新标签页打开查看):



思路一

(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,新手写博客,写错了或者写的不清楚还请帮忙指出,谢谢!

转载请注明:/article/11857832.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: