剑指 Offer 39. 数组中出现次数超过一半的数字
思路:我们在遍历数组的时候记录两个值:1. 数组中的数字;2. 次数。使用一个计数count = 1,当前数res,每当数组中数和当前数res相同,那么count就加1,不相同就减一,因为是找出现的数超过数组的长度的一半,所以最后如果有出现的数超过数组长度一半的,count肯定是大于0的数。
具体步骤:
(1)当遍历到的数组当前数和res相等,即array[i] == res,则执行count加1;
(2)若不相等,则count就减1;
(3)如果count等于0了,说明这个数在这里出现的次数已经被抵消了,重新记录count为1,并将res记录为数组当前这个数array[i];
(4)遍历数组,计数res到底出现了几次,若次数大于array.length / 2则返回res,否则说明没有这个数,返回0。
class Solution {
public int majorityElement(int[] array) {
if (array.length == 0) {
return 0;
}
int res = array[0],count = 1;
for (int i = 0; i < array.length; i++) {
if(array[i] == res){
count ++;
}else{
count --;
}
if(count == 0){
res = array[i];
count = 1;
}
}
count = 0;
for (int i = 0; i < array.length; i++) {
if(array[i] == res) count ++;
}
return count > array.length / 2 ? res : 0;
}
}
思路:排序
数组排序后,如果某个数字出现次数超过数组的长度的一半,则一定会数组中间的位置。所以我们取出排序后中间位置的数,统计一下它的出现次数是否大于数组长度的一半。
class Solution {
public int majorityElement(int[] array) {
Arrays.sort(array);
int length = array.length / 2, count = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == array[length]) {
count++;
}
}
if (count > length) {
return array[length];
} else {
return 0;
}
}
}
思路:哈希表
借助hashmap存储数组中每个数出现的次数,最后看是否有数字出现次数超过数组长度的一半。
class Solution {
public int majorityElement(int[] array) {
HashMap<Integer, Integer> map = new HashMap<>();
int length = array.length / 2;
for (int i = 0; i < array.length; i++) {
if (map.containsKey(array[i])) {
map.put(array[i], map.get(array[i]) + 1);
} else {
map.put(array[i], 1);
}
if (map.get(array[i]) > array.length / 2) {
return array[i];
}
}
return 0;
}
}