版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kaiyang_Shao/article/details/89605861
题目描述
给定一个整数数组,包含n个整数,请找出出现次数大于n/2的数,数组保证存在解。
例如:
input:2 3 3 3 2
output:3
方法一 摩尔投票法
思路:摩尔投票法的基本思想很简单,在每一轮投票过程中,从数组中找出一对不同的元素,将其从数组中删除。这样不断的删除直到无法再进行投票,如果数组为空,则没有任何元素出现的次数超过该数组长度的一半。如果只存在一种元素,那么这个元素则可能为目标元素。
时间复杂度:O(n)
空间复杂度:O(1)
//摩尔投票法
public static int findByMoer(int[] nums){
int cur = 0;
int cnt = 0;
for(int n : nums){
if(cnt == 0){
cur = n;
}
//如果相同则计数加一,否则消除一组
cnt = n == cur ? ++cnt : --cnt;
}
return cur;
}
方法二 先排序后寻找
思路:对数组按照大小进行排序,众数必定出现在中间位置,因为其数量大于数组个数的一半所以不管其大小如何都会覆盖中间位置。
时间复杂度:O(nlogn)
空间复杂度:O(1)
//先排序后找
public static int findBySort(int[] nums){
Arrays.sort(nums);
return nums[nums.length / 2];
}
方法三 map计数法
思路:使用hashmap对数组中的元素进行计数,之后可以通过对map遍历或者排序的方式来获取所要求的值,也可以在更新个数的同时判断出现次数,如果出现次数大于n/2,则输出。
时间复杂度:O(n)
空间复杂度:O(n)
//使用map计数
public static int findByMap(int[] nums){
Map<Integer, Integer> map = new HashMap<>();
int len = nums.length;
int result = 0;
for(int n : nums){
if(!map.containsKey(n)){
map.put(n,1);
}else{
//更新计数
map.replace(n, map.get(n) + 1);
}
if(map.get(n) > len / 2){
result = n;
break;
}
}
return result;
}
方法四 暴力搜索法
思路:对数组中的每个元素进行计数,如果出现次数大于n/2则输出。
时间复杂度:O(n^2)
空间复杂度:O(1)
//暴力搜索法
public static int findByForce(int[] nums){
int result = 0;
int cnt = 0;
int len = nums.length;
for(int i = 0; i <= len / 2; i++){
cnt = 0;
for(int j = i; j < len; j++){
if(nums[i] == nums[j]){
cnt ++;
}
}
if(cnt > len / 2){
result = nums[i];
break;
}
}
return result;
}