问题描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
输入描述:
输入一个数组
输出描述:
输出出现次数超过一半的数字
示例
示例1
输入
[1,2,3,2,2,2,5,4,2]
输出
2
解决思路
分析
- 采用hash的方法。
- 通过第一次遍历找出出现次数最多的数字,第二次遍历统计该数字出现的次数
方法
- 通过hash的方法,借助 hashMap存储统计数字出现的次数,如果发现符合条件的数字,返回
- 通过第一次遍历找出出现次数最多的数字,第二次遍历统计该数字出现的次数
代码实现
// 思路1
public class Solution {
public int MoreThanHalfNum_Solution(int[] array) {
Map<Integer, Integer> temp = new HashMap<>();
int count = array.length / 2 + 1;
for (int i = 0; i < array.length; i++) {
if (temp.containsKey(array[i])) {
int tempCount = temp.get(array[i]);
tempCount++;
if (tempCount >= count) {
return array[i];
}
temp.put(array[i], tempCount);
} else {
temp.put(array[i], 1);
}
}
for (Map.Entry<Integer, Integer> entry : temp.entrySet()) {
if (entry.getValue() >= count) {
return entry.getKey();
}
}
return 0;
}
}
时间复杂度分析:
O(N) :遍历一次数组次数为N,遍历map最大的次数也为N,所以时间复杂度为O(N)
空间复杂度分析:
O(N):假设数组中没有重复的数字,则map存储所有数字出现的次数,所以空间复杂度为O(N)
// 思路2
public class Solution {
public int MoreThanHalfNum2(int[] array) {
// 找出出现次数最多的数字
int res = array[0];
int count = 1;
for (int i = 1; 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 (res == array[i]) {
count++;
}
}
// 判断次数是否达标
if (count > array.length / 2) {
return res;
}
return 0;
}
}
时间复杂度分析:
O(N) :遍历两次数组次数为2N,所以时间复杂度为O(N)。
空间复杂度分析:
O(1):没有使用额外的空间
小伙伴如果想测试的话,可以直接到牛客网这个链接做测试