发布于 

剑指 Offer.39-数组中出现次数超过一半的数字

剑指 Offer.39-数组中出现次数超过一半的数字

题目链接

<剑指 Offer 39. 数组中出现次数超过一半的数字>

问题描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

个人想法(HashMap)

使用hash表存储每个数出现的次数,需要对数组进行两次遍历,时间复杂度为0(n),空间复杂度为O(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public int majorityElement(int[] nums) {
int target = 0;
if(nums.length % 2 == 0){
target = nums.length/2;
}else{
target = (nums.length/2);
}

//hash表实现
HashMap<Integer,Integer> map = new HashMap<>();
for(int num:nums){
if(!map.containsKey(num)){
map.put(num,1);
}else{
map.put(num,map.get(num)+1);
}
}
// 遍历map
Iterator<Map.Entry<Integer,Integer>> it = map.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Integer,Integer> element = it.next();
if(element.getValue() > target){
return element.getKey();
}
}

return -1;
}
}

官方解法

使用摩尔投票算法,简单理解就是一种同归于尽的算法,首先选中数组中的第一个元素,从第二个元素开始进行遍历,当第二个元素与第一个元素不同时,vote-1,相同则vote+1,最后遍历完成还存活的元素,将其视为出现次数最多的元素。二次遍历,确认其数量是否超过半数,若超过半数则返回该数字。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int majorityElement(int[] nums) {
int x = 0,votes = 0,count = 0;
// 摩尔投票
for(int num:nums){
if(votes == 0)
x = num;
votes += num==x?1:-1;
}

// 验证当前元素是否超过了一半
for(int num:nums){
if(num == x){
count++;
}
}

return count > nums.length/2?x:0;
}
}

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 @John Doe 创建,使用 Stellar 作为主题。