给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:[3,2,3]
输出:3
示例 2:
输入:[2,2,1,1,1,2,2]
输出:2
进阶:
- 尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
解法分析: 1、使用map记录<元素,出现次数>,如果次数超过n/2 即为要查找的多数元素 代码如下:
public static int majorityElement(int[] nums) {
Map<Integer,Integer> map = new HashMap<>();
//统计多数元素 满足结果
int halfLen = nums.length/2;
for (int i = 0; i < nums.length; i++) {
int num = nums[i];
//元素次数 初始化是1
int count = 1;
if(map.containsKey(num)){
count = map.get(num);
count++;
}
//判断是否是多元素
if(count>halfLen){
return num;
}
System.out.println(num+"元素,存储次数为 " + count);
map.put(num,count);
}
return -1;
}
2、排序后取中间元素,即为多数元素(多数元素个数超过数组的一半以上)
[3,2,3]
[2,3,3]
[2,2,1,1,1,2,2]
[1,1,1,2,2,2,2]
3、投票算法 将元素当做候选人,如果新元素和候选人相同,次数+1,不同次数-1(代表抵消),如果次数=0,候选人更新
[2,2,1,1,1,2,2]
元素 次数 候选人
2 1 2
2 2 2
1 1 2
1 0
1 1 1
2 0
2 1 2
本质上 多数元素的出现次数一定大于其他所有元素出现的次数的 总和 所以候选人的次数经过抵消后最终剩余的一定是多数元素 代码如下:
public static int majorityElement2(int[] nums) {
//候选人
int candiddate = -1;
//出现次数
int count = 0;
for (int i = 0; i < nums.length; i++) {
//如果出现次数为0 重置候选人
if (count == 0) {
candiddate = nums[i];
}
//根据新元素是否等于候选人 进行次数的加减操作
if (candiddate == nums[i]) {
count++;
} else {
count--;
}
System.out.println("元素" + nums[i] + ",词素" + count + ",候选人" + candiddate);
}
return candiddate;
}