169. 多数元素(Java实现)
题目:给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。
输入: [3,2,3]
输出: 3
输入: [2,2,1,1,1,2,2]
输出: 2
说明:
本题题面中没有给出数据范围,但最简单的暴力方法(即枚举数组中的每个元素,再遍历一遍数组统计其出现次数,时间复杂度为 O(N^2)的算法)会超出时间限制,因此我们需要找出时间复杂度小于 O(N^2) 的优秀做法。
方法一:Hash映射(HashMap)
- 将数组中的数字作为键,元素出现的次数作为值构建Hash表。实现就是遍历一遍,如果map中没有当前键就插入键,值为1;如果已经有了当前键,则将对应的值加1;最后遍历一遍map的值,看谁大于nums.length/2即可。
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
class Solution {
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i=0;i<nums.length;i++){
if(map.containsKey(nums[i])){
map.put(nums[i], map.get(nums[i])+1);
}else {
map.put(nums[i], 1);
}
}
//用迭代器遍历
Set<Entry<Integer,Integer>> ss = map.entrySet();
for(Iterator iterator = ss.iterator();iterator.hasNext();){
Entry e = (Entry) iterator.next();
if((int)e.getValue() > nums.length/2){
return (int) e.getKey();
}
}
return 0;
}
}
-
结果:
-
算法复杂度分析:
方法二:排序
- 因为题意说明了一定存在多数元素,所以数组排序后,中间的元素一定就是要找的。
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
}
- 结果:
- 算法复杂度分析:
方法三:摩尔投票(这个真的学习了!)
-
摩尔投票法:(LeetCode上有人发的解释,觉得简单易懂,比官方的要好)
核心就是对拼消耗。
玩一个诸侯争霸的游戏,假设你方人口超过总人口一半以上,并且能保证每个人口出去干仗都能一对一同归于尽。最后还有人活下来的国家就是胜利。
那就大混战呗,最差所有人都联合起来对付你(对应你每次选择作为计数器的数都是众数),或者其他国家也会相互攻击(会选择其他数作为计数器的数),但是只要你们不要内斗,最后肯定你赢。
最后能剩下的必定是自己人。
class Solution {
public int majorityElement(int[] nums) {
int count=0;
int temp = nums[0];
for(int i=0;i<nums.length;++i){
if(nums[i]==temp){
++count;
}else{
--count;
if(count==0){
temp=nums[i+1];
}
}
}
return temp;
}
}
-
结果:
-
算法复杂度分析: