题目:
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
一开始看到此题的时候,我想的是用map集合去统计每个元素出现的次数,然后次数最多就是众数(假设众数一定存在,如果众数不一定存在的话就还要加上判断)。代码如下“:
public int majorityElement(int[] nums) {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
int time = 0;
int result = 0;
//统计元素出现的次数
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 (Map.Entry<Integer,Integer> str : map.entrySet()) {
if(str.getValue()>nums.length/2)
{
result = str.getKey();
break;
}
}
return result;
这种做法是可行的,但是还有更加简便的方法,那就是摩尔投票算法。
摩尔投票算法的思路是:先定义两个参数,一个是计数器和一个是存储大多数值的参数,初始值都为0,遍历数组,判断计数器是否等于0,如果计数器为0,那么将计数器加1,同时将此时的元素赋值给大多数,如果不为0则再次进行判断,比较大多数那个参数的值和此时元素,如果相等则将计数器加1,不相等则计数器减1。(归根到底就是众数和其他元素的消除操作)
代码如下:
public int majorityElement(int[] nums) {
//摩尔投票算法
int result = 0;
int time = 0;
for(int i = 0;i<nums.length;i++){
if(time == 0)
{
result = nums[i];
time ++;
}else if(result == nums[i])
time ++;
else
time--;
}
return result;
}
总结:摩尔投票算法可以解决:在一个数组中,找出在数组中出现次数大于n/2(或n/3等等)的数(投票选举,输入最终得选的人)