您的位置:首页 > 其它

leetcode_169(主元素查找)

2016-12-09 14:22 288 查看
一、题目大意:

给定size 为n的数组,查找出主元素,就是出现次数大于n/2次的元素。你可以假定数组非空,而且主元素一定存在。

二、分析

1,不难想到,出现半数以上的元素最多只有一个。

2,选出出现次数达到半数以上的元素,最笨的方法当然就是对数组中出现的每一个元素,都遍历一遍数组记录下其出现频率,通过与比较确定是否符合要求。这样就可以在的时间内,用O(1)空间解决问题。但是时间复杂度O(n^2),这里不做介绍。

3,hash表来存储每个元素出现的次数,这样就可以得到一个时间复杂度和空间复杂度都是O(n)的解决方案。这里我们不自己构造hash函数,使用java自带的hashMap,时间上也不是很快。

4,随机化方法,每次随机产生一个位置,对这个位置的数进行计数,看是不是主元素,时间O(n)。

5,Moore’s Voting Algorithm算法。时间O(n)

算法的基本思想非常简洁: 每次都找出一对不同的元素,从数组中删掉,直到数组为空或只有一种元素。 不难证明,如果存在元素e出现频率超过半数,那么数组中最后剩下的就只有e。当然,最后剩下的元素也可能并没有出现半数以上。比如说数组是[1, 2, 3],最后剩下的3显然只出现了1次,并不到半数。排除这种false positive情况的方法也很简单,只要保存下原始数组,最后扫描一遍验证一下就可以了。

三、java求解

1,hash表:

public static int majorityElement(int[] nums) {
if(nums.length == 0)
return -1;
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i=0;i<nums.length;i++) {
if(map.get(nums[i]) == null) {
map.put(nums[i], 1);
}else {
map.put(nums[i], map.get(nums[i])+1);
}
}
for(Integer key:map.keySet()) {
if(map.get(key) > nums.length/2)
return key;
}
return -1;
}


2,随机化方法

public static int majorityElemen2(int[] nums) {
int count = 0;
while(true) {
int n = (int) (Math.random()*(nums.length-1));
for(int i=0;i<nums.length;i++) {
if(nums[i] == nums
) {
count++;
}
}
if(count > nums.length/2) {
return nums
;
}else {
count = 0;
continue;
}
}
}


3,算法

public static int majorityElemen3(int[] nums) {
int elem = 0;
int count = 0;

for(int i=0;i<nums.length;i++) {
if(count == 0) {
elem = nums[i];
count = 1;
}else {
if(elem == nums[i]) {
count++;
}else {
count--;
}
}
}

return elem;
}


四、算法的python实现

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

return elem
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 遍历 算法