题目
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
思路
因为数组非空的,而且一定存在多数元素,即一定存在一个在数组中,元素个数大于n/2的元素,那么,如果我们进行一次排序,下标为n/2的那个数,一定是众数【因为该元素的个数大于n/2个,就算没有数比该众数小或者大,这这个在排完序之后,也肯定会占据n/2的位置】
代码
import java.util.Arrays;
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
}
结果
因为采取快排,所以时间复杂度是O(nlogn),没有额外的空间复杂度。不过,这个是一个超级暴力的解法,不好。
改进思路
可以利用一个hashmap来存放数值与其对应的个数。但是,因为这个,需要遍历的时间就为O(n),遍历一遍数组,还得遍历一下hashmap,速度肯定会降低。不过也是一种解题方法。
改进代码
import java.util.HashMap;
import java.util.Map;
class Solution {
public int majorityElement(int[] nums) {
//利用hashmap来解答
Map <Integer,Integer> count=new<Integer, Integer>HashMap();
int length=nums.length;//数组长度
//把所有的数字存放到hashmap里面
for (int i=0;i<length;++i)
{
if (!count.containsKey(nums[i]))
count.put(nums[i],1);
else
count.put(nums[i],count.get(nums[i])+1);
}
int max_count=Integer.MIN_VALUE;
int result=0;// 结果存放 nums[i]
for (int key : count.keySet()){
if (count.get(key)>max_count)
{
max_count=count.get(key);
result=key;//改变key值
}
}
return result;
}
}
结果
利用了一个容器的特性,速度肯定没有第一种方法快,只是为了寻找不同的方法而已。
再改进思路
刚刚百度了一下,顺便去看了一下题解,有个投票算法。就是说,如果把众数定为正1,非众数定为-1,那么相加起来的和,也就会是正数。这个是投票算法的指导思想。从结果我们就可以看出,众数的数目是大于非众数的。
代码
class Solution {
public int majorityElement(int[] nums) {
int count = 0;//计算候选人的个数
Integer candidate = null;//候选人
int length=nums.length;
for (int i=0;i<length;++i) {
if (count == 0) //如果当前的候选人个数为0,那么就把目前这个数值作为候选人
{
candidate = nums[i];
}
//如果,接下来的数与候选人相等,那么就加1,如果不等,那么就减1
count += (nums[i] == candidate) ? 1 : -1;
}
/*因为众数的个数是大于n/2的,所以,最终的候选人会被选出来并且个数为正*/
return candidate;
}
}
结果
经过学习了投票算法,觉得很妙!