【剑指offer】39.数组中出现次数超过一半的数字
39.数组中出现次数超过一半的数字
面试题39. 数组中出现次数超过一半的数字
难度简单19
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2
1.哈希表
//哈希表
//1.将数组中元素作为key value为出现的次数
//2.遍历哈希表中所有key 找出出现最大的次数
// time :O(n) 遍历数组n次
// space : 将元素存储到哈希表中所占用的空间
public int majorityElement(int[] nums) {
if(nums == null || nums.length == 0){
return -1;
}
Map<Integer,Integer> results = new HashMap<>();
for(int i=0;i<nums.length;i++){
if(!results.containsKey(nums[i]))
results.put(nums[i],1);
else
results.put(nums[i],results.get(nums[i])+1);
}
Map.Entry<Integer, Integer> majorityEntry = null;
for (Map.Entry<Integer, Integer> entry : results.entrySet()) {
if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) {
majorityEntry = entry;
}
}
return majorityEntry.getKey();
}
2.排序
// time : (OlogN) 数组排序需要的时间
// space : (logN) 数组排序需要的外部存储空间 语言自身的排序空间是OlogN
// ps : 当数组中有大于一半以上的数据时,如果将数组进行排序,那么中间下标位置一定是众数的下标。
// 无论是偶数 还是 奇数。
// 众数 : 在一组数据中出现次数最多的数字。
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
3.Boyer-Moore 投票算法
// Boyer-Moore 投票算法
// 核心思想
// 如果候选人不是maj 则 maj,会和其他非候选人一起反对 会反对候选人,所以候选人一定会下台(maj==0时发生换届选举)
// 如果候选人是maj , 则maj 会支持自己,其他候选人会反对,同样因为maj 票数超过一半,所以maj 一定会成功当选
// time : O(n) 一次loop array
// space : O(1)
public int majorityElement(int[] nums) {
if(nums == null || nums.length == 0) return -1;
int count = 0;
Integer candidate = null;
for(int num : nums){
if(count == 0){
candidate = num;//更换候选人
}
//count += ((num == candidate) ? 1 : -1);
count += (num == candidate) ? 1 : -1;
}
return candidate;
}