剑指 Offer 39. 数组中出现次数超过一半的数字
剑指 Offer 39. 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:
1 <= 数组长度 <= 50000
解一:排序
把数组排序后,中位数就是出现次数最多的数(可以用反证法证明)
时间复杂度:数组排序的时间复杂度,java的Arrays.sort()用的快排,时间复杂度是O(nlogn)
空间复杂度:O(1)
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
//把数组排序后,中位数就是出现次数过半的数
int n=nums.length;
return nums[n/2];
}
}
解二:哈希表
遍历数组,并统计每个数出现的次数,统计结果存入HashMap,再遍历HashMap找到出现次数最多的数。
时间复杂度:O(n)
空间复杂度:O(n)
class Solution {
public int majorityElement(int[] nums) {
HashMap<Integer,Integer> statistics=new HashMap<>();
for(int num:nums){
if(statistics.containsKey(num)){
int count=statistics.get(num);
count++;
statistics.put(num,count);
}else{
statistics.put(num,1);
}
}
int res=nums[0];
for(int num : statistics.keySet()){
if(statistics.get(num)>(nums.length/2)){
res=num;
break;
}
}
return res;
}
}
解三:摩尔投票
-
记当前出现的次数最多的数为curr,遍历到的数为num,如果curr==num,则count++,否则count--(相当于一个相等的数和一个相等的数抵消)。当count为零时,令curr为当前的num。遍历完的curr即为出现次数超过一半的数。
-
时间复杂度:O(n)
-
空间复杂度:O(1)
class Solution {
public int majorityElement(int[] nums) {
int curr=0;
int count=0;
for(int num:nums){
if(count==0){
//先判断是否为0
curr=num;
}
if(num==curr) {
count++;
}else{
count--;
}
}
return curr;
}
}

浙公网安备 33010602011771号