数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2
方法一:
哈希表统计法: 遍历数组 nums ,用 HashMap 统计各数字的数量,最终超过数组长度一半的数字则为众数。此方法时间和空间复杂度均为 O(N)O(N) 。
public static int majorityElement1(int[] nums) {
Map<Integer , Integer> map = new HashMap<>();
int i = 0;
for(i = 0 ; i < nums.length ;i++){
if(!map.containsKey(nums[i])){
map.put(nums[i] , 1);
}else {
map.put(nums[i] , map.get(nums[i]) + 1);
}
int value = map.get(nums[i]);
if(value > nums.length / 2){
break;
}
}
return nums[i];
}
方法二:摩尔投票法: 核心理念为 “正负抵消” ;时间和空间复杂度分别为 O(N)O(N) 和 O(1)O(1) ;是本题的最佳解法。
算法流程:
初始化: 票数统计 votes = 0votes=0 , 众数 xx;
循环抵消: 遍历数组 nums 中的每个数字 numnum ;
当 票数 votesvotes 等于 00 ,则假设 当前数字 numnum 为 众数 xx ;
当 num = xnum=x 时,票数 votesvotes 自增 11 ;否则,票数 votesvotes 自减 11 。
返回值: 返回 众数 xx 即可。
//摩尔投票法
public static int majorityElement2(int[] nums) {
int Moore = nums[0];
int sum = 1;
int i = 1;
while (i < nums.length) {
sum = Moore == nums[i] ? ++sum : --sum;
if(sum == 0 && ++i < nums.length){
sum = 1;
Moore = nums[i];
}
++i;
}
return Moore;
}
作者:jyd
链接:https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/solution/mian-shi-ti-39-shu-zu-zhong-chu-xian-ci-shu-chao-3/
来源:力扣(LeetCode)