数组中出现次数超过一半的数字(java三种解法)
题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。
题解:
解一:
利用额外空间。创建一个map函数记录数组中每个元素和它出现的次数。
代码:
public static int majorityElement(int[] nums) {
//哈希表法
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
int n = nums.length/2;
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);
}
if(map.get(nums[i]) > n) {
return nums[i];
}
}
return -1;
}
解二:
排序。先把数组排好序,由于目标元素个数超过数组长度的一半,那么排好序之后目标元素一定铺满了超过数组的前半部分(或后半部分),数组中间位置上一定有目标元素。
代码:
public static int majorityElement(int[] nums) {
//排序法
Arrays.sort(nums);
int n = nums.length/2;
return nums[n];
}
解三:
摩尔投票法。从nums[0] (一个武士)开始,向后遍历,遇到和自己相同的元素就计数count加一(武力值加一),遇到和自己不同的元素就计数count减一(武力值减一),当count减为0时(就没有武力值了,死掉了),此时换成当前遍历到的元素(最后杀死他的武士),继续战斗,最终count>0时保持的元素(能活到最后的那个武士就是)要找的多量元素。
代码:
public static int majorityElement(int[] nums) {
//摩尔投票法
int count = 0, temp = nums[0];
for(int i = 0; i < nums.length; i ++) {
if(nums[i] == temp) {
count ++;
}else if(nums[i] != temp && count > 0) {
count --;
}else {
temp = nums[i];
}
}
return temp;
}