题目描述
给定一个大小为 n 的数组,找到其中的多数元素。
多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
解法一:排序
- 最简单,由题目描述可知,多数元素为出现次数大于n/2,那么排序后数组中间的数一定为多数元素
- 如果使用语言自带的排序算法,需要使用 O(logn) 的栈空间。如果自己编写堆排序,则只需要使用 O(1) 的额外空间。
- 时间复杂度为排序时间复杂度,性能较差,对比排序算法的时间复杂度至少为O(nlogn)
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
解法二:HashMap
- 遍历过程中统计每个数字出现的个数即可。
- 可以确定的是,超过半数的数字一定有且只有一个。在计数过程中如果出现了超过半数的数字,直接返回即可
- 时间复杂度为O(n),空间复杂度为O(n) 性能扔较差
public int majorityElement(int[] nums) {
HashMap<Integer,Integer> map = new HashMap<>();
int n = nums.length;
for(int i = 0;i<nums.length;i++){
int before = map.getOrDefault(nums[i],0);
if(before==n/2){
return nums[i];
}
map.put(nums[i],before+1);
}
return -1;
}
解法三:摩尔投票法
- 观察代码 简单理解为正反相抵消,最终一定为count>0,且flag存储值为众数
- 时间复杂度O(n),空间复杂度O(1)
- 牛逼
public int majorityElement(int[] nums) {
int count = 0;
int flag = 0;
for(int i=0;i<nums.length;i++){
if(count == 0 ){
flag = nums[i];
}
count += (nums[i] == flag)?1:-1;
}
return flag;
}