题目链接
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,新手写博客,写错了或者写的不清楚还请帮忙指出,谢谢!
转载请注明:http://blog.csdn.net/coder_orz/article/details/51407713