【刷题力扣】数组中出现次数超过一半的数字

数组中出现次数超过一半的数字_牛客题霸_牛客网

描述

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

例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

数据范围:n≤50000n≤50000,数组中元素的值 0≤val≤100000≤val≤10000

要求:空间复杂度:O(1),时间复杂度 O(n)

输入描述:

保证数组输入非空,且保证有解

解题思路

最开始想到的肯定是使用hashmap,使用哈希表进行计数,如果发现某个元素数量超过总数一半,说明找到了答案。但是空间复杂度不满足要求。

可以使用著名的 摩尔投票算法 (Boyer-Moore Voting Algorithm)。这个算法的时间复杂度是 O(n),并且只需要常数级别的额外空间 O(1)。简单来说每次将两个不同的元素进行「抵消」,如果最后有元素剩余,则「可能」为元素个数大于总数一半的那个。

摩尔投票算法的核心思想是:

  1. 维护一个候选元素和一个计数器。
  2. 遍历数组:
    • 如果计数器为0,将当前元素设为候选元素,并将计数器设为1。
    • 如果当前元素是候选元素,增加计数器。
    • 如果当前元素不是候选元素,减少计数器。
  3. 最后,候选元素可能是出现次数超过数组长度一半的数字。

注意:

这一算法应用的问题原型是在集合中寻找可能存在的多数元素,这一元素在输入的序列重复出现并占到了序列元素的一半以上;在第一遍遍历之后应该再进行一个遍历以统计第一次算法遍历的结果出现次数,确定其是否为众数;如果一个序列中没有占到多数的元素,那么第一次的结果就可能是无效的随机元素。

实现代码

java 复制代码
public int MoreThanHalfNum_Solution (int[] numbers) {
        // write code here
        int candidate = numbers[0];
        int count = 1;

        // Phase 1: 确定候选
        for (int i = 1; i < numbers.length; i++) {
            if (numbers[i] == candidate) {
                count++;
            } else {
                count--;
                if (count == 0) {
                    candidate = numbers[i];
                    count = 1;
                }
            }
        }

        // Phase 2: 验证候选是否满足要求
        count = 0;
        for (int num : numbers) {
            if (num == candidate) {
                count++;
            }
        }

        if (count > numbers.length / 2) {
            return candidate;
        } else {
            return -1;
        }
    }
相关推荐
郝学胜-神的一滴4 分钟前
李航《机器学习方法》全面解析与高效学习指南
人工智能·python·算法·机器学习·数学建模·scikit-learn
CS创新实验室5 分钟前
奈奎斯特定理:信号处理与通信领域的基石理论
计算机网络·算法·信号处理·奈奎斯特定理
雪花desu9 分钟前
【Hot100-Java简单】/LeetCode 283. 移动零:两种 Java 高效解法详解
数据结构·python·算法
随意起个昵称9 分钟前
【做题总结】顺子(双指针)
c++·算法
一杯咖啡Miracle16 分钟前
UV管理python环境,打包项目为docker流程
python·算法·docker·容器·uv
玉树临风ives21 分钟前
atcoder ABC438 题解
数据结构·算法
算法与编程之美29 分钟前
探索不同的损失函数对分类精度的影响
人工智能·算法·机器学习·分类·数据挖掘
MSTcheng.34 分钟前
【C++】平衡树优化实战:如何手搓一棵查找更快的 AVL 树?
开发语言·数据结构·c++·avl
-Excalibur-34 分钟前
ARP RIP OSPF BGP DHCP以及其他计算机网络当中的通信过程和广播帧单播帧的整理
c语言·网络·python·学习·tcp/ip·算法·智能路由器
刃神太酷啦35 分钟前
Linux 底层核心精讲:环境变量、命令行参数与程序地址空间全解析----《Hello Linux!》(7)
linux·运维·服务器·c语言·c++·chrome·算法