剑指Offer-数组中出现次数超过一半的数字
题目描述#
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路#
思路一:
利用HashMap记录每个数字以及数字出现的次数,没出现过的就放进去,出现过的就累加,若出现次数大于长度一半,返回此数,否则返回0。
思路二:
利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题
使用 count 来统计一个元素出现的次数,当遍历到的元素和统计元素不相等时,令 count--。如果前面查找了 i 个元素,且 count == 0 ,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 count 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目依然多于 (n - i) / 2,因此继续查找就能找出 majority。
代码实现#
package Array;
import java.util.HashMap;
/**
* 数组中出现次数超过一半的数字
* 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
* 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
*/
public class Solution42 {
public static void main(String[] args) {
Solution42 solution42 = new Solution42();
int[] array = {1, 2, 3, 2, 2, 2, 5, 4, 2};
System.out.println(solution42.MoreThanHalfNum_Solution_2(array));
}
/**
* 利用 Boyer-Moore Majority Vote Algorithm(摩尔投票算法)来解决这个问题
*
* @param array
* @return
*/
public int MoreThanHalfNum_Solution_2(int[] array) {
int majority = array[0];
for (int i = 1, count = 1; i < array.length; i++) {
count = array[i] == majority ? count + 1 : count - 1;
if (count == 0) {
majority = array[i];
count = 1;
}
}
int count = 0;
for (int val : array) if (val == majority) count++;
return count > array.length / 2 ? majority : 0;
}
/**
* 利用HashMap记录每个数字以及数字出现的次数
*
* @param array
* @return
*/
public int MoreThanHalfNum_Solution(int[] array) {
if (array == null || array.length == 0)
return 0;
HashMap<Integer, Integer> map = new HashMap<>();
int count;
for (int val :
array) {
if (!map.containsKey(val)) {
map.put(val, 1);
} else {
count = map.get(val);
map.put(val, ++count);
}
if (map.get(val) > array.length / 2) {
return val;
}
}
return 0;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?