【五种方法解决】找出数组中出现次数超过数组长度一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。 如果不存在则输出0。 题目分析: 由于要输出的这个数超过数组长度的一半 所以不难理解 如果存在的话 这个数一定是排完序后的数组的中间元素 因此我们将数组有序之后 用一个count记录... 阅读详情
AI摘要

本文介绍了剑指Offer JZ28题的五种解法,包括利用Map统计频率、排序求中间值、抵消法、快排思想及目标数字与其他数字差值的方法,旨在找出数组中出现次数超过一半的数字。

剑指offerJZ28:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
这道题是在面试时常问的一道题,有多种解法,我们分别看一下;

方法一:利用map

利用map的key -value模型来存放arr[i]和相对应出现的次数,最后用次数去跟数组长度一半去比较,大于则就是;比如1,2,3,2,2,2,5,4,2;就是1出现一次、2出现5次、3.4.5各出现一次;返回的就是2;

public static int solution1(int[] arr){
        //利用map的key value模型来存放arr[i]和相对应出现的次数
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<arr.length;i++){
            if(map.containsKey(arr[i])){
               map.put(arr[i],map.get(arr[i])+1);//已经存在就给value加1
            }
            else{
                map.put(arr[i],1);
            }
        }
        for(Map.Entry<Integer,Integer> entry:map.entrySet()){
            if(entry.getValue()>arr.length/2){
                return entry.getKey();
            }
        }
        return 0;
    }

方法二:排序求中间值

出现的次数超过长度一半,那给数组排序以后,它一定处在最中间的位置;比如1,2,3,2,2,2,5,4,2排完序是1,2,2,2,2,2,3,4,5,;接下来去统计数组中跟arr[mid]值一样的元素,相等count++;如果count的值大于mid,则说明存在输出,否则返回0;

 public static int solution2(int[] arr){
        //先对数组排序,如果这个数存在,那它一定在arr[mid]的位置,
        Arrays.sort(arr);
        int count=0;
        int mid=arr.length/2;
        for(int i=0;i<arr.length;i++){
            if(arr[i]==arr[mid]){
                count++;
            }
        }
        if(count>mid){//出现的次数超过mid,则返回它;
            return arr[mid];
        }
        return 0;
    }

方法三:抵消法

将target和其他元素进行抵消,由于target出现的次数大于别的元素,所以最后剩下的就是我们要找的;在遍历数组的时候保存两个值:数组中的一个元素(target) 和 该元素出现的次数(times)。当我们遍历到下一个元素的时候,如果下一个元素和我们之前保存的元素相等,则次数加1,如果下一个元素和我们之前保存的元素不相等,则次数减1。如果次数为零,我们需要保存下一个元素,并且把次数重设为1。由于目标元素出现的次数比其它所有元素出现的次数之和还要多,所以目标元素肯定是最后一次把次数设为1时对应的元素。
*

public static int solution3(int[] arr){
        //抵消法:将target和其他元素进行抵消,由于target出现的次数大于别的元素,所以最后剩下的就是我们要找的
        //1,4,5,7,2,4,5,4,6,4,5,4,4,4,4
        int target=arr[0];//target先设为arr[0];
        int times=1;
        for(int i=0;i<arr.length;i++){
            if(times==0){//重新设置
                target=arr[i];
                times=1;
            }
            else
            {
                if(arr[i]==target){
                    times++;
                } else {
                    times--;
                }
            }
        }
        return target;
    }

方法四:利用快排的思想

使用partition()方法获取基准元素的下标。若基准元素的下标为length/2,则基准元素是数组的中位数,即基准元素就是目标元素。若基准元素的下标大于length/2,则数组的中位数位于基准元素的左边。若基准元素的下标小于length/2,则数组的中位数位于基准元素的右边。

 public static int solution4(int[] arr){
        int low=0;
        int high=arr.length-1;
        int mid=(high-low)/2;
        int index=partition(arr,low,high);
        while(index!=arr.length/2){
            if(index<arr.length/2){
                low=index+1;
                index=partition(arr,low,high);
            }
            else{
                high=index-1;
                index=partition(arr,low,high);
            }
        }
        int num=arr[index];
        int times=0;
        for(int i=0;i<arr.length;i++){
            if(arr[i]==num){
                times++;
            }
        }
        if(times*2>arr.length){
            return num;
        }
        return 0;
    }
    public static int partition(int[] arr,int low,int high){
        int key=arr[low];
        while(low<high){
            while(low<high&&arr[high]>=key){
                high--;
            }
            int temp=arr[low];
            arr[low]=arr[high];
            arr[high]=temp;
            while(low<high&&arr[low]<=key){
                low++;
            }
            temp=arr[low];
            arr[low]=arr[high];
            arr[high]=temp;
        }
        return low;
    }

方法五:target-other>=1

和方法三思想基本一致,因为这个数字出现次数超过数组长度的一半,所以目标数字的个数 减去其他数字的个数总和 一定是大于等于1的,当我们遇到目标值时+1,否则-1,当count为0时重新设置目标值,最后记录的位置一定是目标数字

public  static int solution(int[] arr){
        int count=0;
        int aws=0;
        for(int i=0;i<arr.length;i++){
            if(count==0){
                aws=arr[i];
            }
            if(arr[i]==aws){
                count++;
            } else {
                count--;
            }
        }
        return aws;
    }
数组中出现次数超过一半的数字 摘要: 寻找数组中的多数元素(出现次数超过⌊n/2⌋)可通过三种方法实现: 哈希表统计法:统计元素频率,时空复杂度均为O(n)。 排序法:排序后取中间元素,时间复杂度O(nlogn),空间复杂度O(1)或O(n)。 Boyer-Moore投票算法(最优):通过计数器维护候选,时间复杂度O(n),空间O(1)。 关键点:多数元素数量超过其他元素总和,投票算法高效且节省空间。测试用例涵盖常规、全同及边界情况。扩展问题包括处理无多数元素或n/3阈值场景。实际应用包括选举计票和异常检测,面试推荐优先解释投票算法。 阅读详情

相关推荐

全志T113s3主线linux开发(0)--基础准备

嵌入式Linux设备的启动大概是三步:1)启动芯片+内存:常见的是Uboot,不过全志的Uboot主线对SPI NAND 不太友好,用TF卡就方便。对于T113S芯片,推荐使用Awboot,简陋但快速。开发阶段用这个就方便好多,对SPINAND支持也方便。2)启动linux内核:主线内核以下通篇都用6.13以上的内核。对比tina5.0还在用5.4 ,主要是性能、安全上有变化。6.0以上内核在devicetree的编写具体格式上有了变化,网上大量tina5.0和5.4内核的编写方式不适用。

2301_79234138的博客 2247

【面试题】数组中出现次数超过一半的数字(三种解法详解)

题目描述 解法一:哈希表统计法 遍历数组 nums,用 HashMap 统计各数字出现的次数,最终超过数组长度一半的数字则为要查找的结果。此方法时间和空间复杂度均为 O(N)。 Java class Solution { HashMap<Integer, Integer> map = new HashMap<> (); public int majorityElement(int[] nums) { if(nums.length == 0) retu

Mr_SCX的博客 3009

保姆级教程:用DaVinci Configurator & Developer从零搭建AUTOSAR OS(TC2xx三核实战)

本文提供了一份详细的AUTOSAR OS配置指南,使用DaVinci Configurator和Developer工具从零开始搭建Infineon TC2xx三核系统。涵盖多核配置协同逻辑、版本兼容性陷阱及验证错误的解决方案,帮助开发者在3小时内构建可运行的多核OS框架。

weixin_33940469的博客 313

出现次数超过一半的数字

题目描述 题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。 分析与解法 一个数组中有很多数,现在我们要找出其中那个出现次数超过总数一半的数字,怎么找呢?大凡当我们碰到某一个杂乱无序的东西时,我们人的内心本质期望是希望把它梳理成有序的。所以,我们得分两种情况来讨论,无序和有序。 解法一 如果无序,那么我们是不是可以先把数组中所有这些数字先进行排序(至

qisefengzheng的专栏 总有一天你将破蛹而出 895

疫情数据分析的“核武器”!JHU CSSE COVID-19数据集超深度解析与实战指南(附代码)

在面对这场没有硝烟的战争时,除了医护人员在前线与病毒搏斗,还有一群默默的英雄——数据科学家和分析师,他们利用手中的“数据武器”,昼夜不停地监测、分析、预测疫情走势,为政府决策、资源调配、公众科普提供了至关重要的支撑。同时,由于某些国家(如美国、加拿大、澳大利亚、中国等)的数据细化到省/州级别,为了得到国家层面的总数据,我们需要按国家和日期进行聚合。正是在这样的背景下,经过这些步骤,我们已经得到了一个包含了累计数据、每日新增数据和活跃病例数的完整数据集,可以开始进行深入的分析和可视化了!

wylee的博客 1165

基于STM32单片机设计的智能坐垫_431

本文设计了一款基于STM32F103C8T6单片机的智能坐垫系统,该系统集成了压力传感器、SHT30温湿度传感器、薄膜加热垫、涡轮风机、语音播报模块、OLED显示屏及HC-05蓝牙模块,实现了对用户就坐状态与坐垫微环境的实时监测与智能调控。系统通过压力传感器检测用户就坐情况,自动启动久坐计时并触发语音提醒;温湿度数据用于控制通风与加热功能,以改善座椅舒适性;用户可通过按键或手机APP设置久坐时长、手动开关通风与加热,并通过OLED屏或APP实时查看环境参数与计时状态。本设计体现了嵌入式系统在健康关怀与舒适性

409

数组中出现次数超过数组长度一半的数(4种解法)

题目: 数组的长度为n,找出数组中出现次数大于长度一半的数,如果存在返回这个数,不存在返回0。 解法一: 先对数组进行排序,然后找到arr[n/2]的数(如果存在数组中长度超过一半的数,最中间的数就是这个数),遍历数组如果arr[n/2]相等的数超过n/2;就是这个数,没有就返回零。(时间复杂度O(nlogn)) public static int getValue(int[] gift...

qq_41552331的博客 3384

【系统移植】 移植主线U-Boot(v2024.01-rc3)到RK3399

[系统移植] 移植主线U-Boot(v2024.01-rc3)到RK3399

Systemcall名屋 1003

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

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。因为2在数组中出现的次数超过5次,所以输出2. public class overhalfprint { public static int moreThanHaft(int[] num){ int result = -1; ...

Sophisticate11的博客 1598

RK3568平台(USB篇)USB基础知识

现象:把USB设备比如Android手机接到PC答1:是USB控制器,是USB控制器内嵌的root hub.答2. windows里已经有了USB的总线驱动程序,接入USB设备后,是"总线驱动程序"知道你是"android phone"提示你安装的是"设备驱动程序"。USB总线驱动程序负责:识别USB设备, 给USB设备找到对应的驱动程序。答3. PC的USB口内部,D-和D+接有15K的下拉电阻,未接USB设备时为低电平USB设备的USB口内部,D-或D+接有1.5K的上拉电阻;

weixin_49303682的博客 1658

【机器学习-09】特征工程

特征工程是机器学习模型构建的初步工作,但它的重要性却贯穿整个模型生命周期。在进行特征工程时,我们需要充分利用数据科学的知识和技巧,结合具体的应用场景和业务需求,来制定出最合适的特征提取和转换策略。只有这样,我们才能为机器学习模型提供最有价值的输入,从而使其发挥出最大的潜力。总之,特征工程是机器学习中的一项关键任务,它需要我们用心去探索、去实践、去创新。只有不断地优化和完善特征工程的过程,我们才能构建出更加准确、更加可靠的机器学习模型,为实际应用带来更大的价值。

qq_38614074的博客 2万+

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

问题:数组中一个数字出现的次数超过了数组长度的一半,找出这个数字。 我这里给出的是只考虑了正常情况的算法,没有考虑数组无效,以及不符合次数超过数组长度一半的情况。 思路: (1)将数组排序(排序的原因是为了下面方便统计出次数) (2)排好序后,分别统计每个元素出现的次数,并对应记录相应的元素。 (3)找出次数最多的元素。 (补充,其实排好序后不需要统计次数了,应为这个数字出现的次数超过

hairongtian的专栏 3796

linux那些事之numa balance

numa balance numa balance是页迁移技术最重要也是最开始使用应用的技术,主要是为解决由于调度器进程在两个node迁移造成访问内存性能问题。 numba balance通过页迁移技术,将不在运行节点的内存迁移到所运行的节点上。对应numa balance要注意几点: 防止进程在两个节点之前来回切换造成频繁进行页迁移(ping pang现场)从而影响性能。numa balance本身就是为了提高性能,不能因为造成频繁页迁移而对性能进行一个反向优化。 多个线程分布在不同线程 访.

weixin_42730667的博客 3908

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

参考链接:https://yq.aliyun.com/articles/642782 一、题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 二、解题思路 解法一:基于Partition 函数的O(n)算法 数组中有一个数字出现的次数超过了数组长度的一半。如果把这个数组排序,那么排序之后位于数组中间的数字一定就是那个出现次数超过数组长度一半的数字。也就是说,这个数字就是统计学上的...

皮卡丘的博客 2088

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

找出数组中出现次数超过数组长度的一半的数字

文章目录找出数组中出现次数超过数组长度的一半的数字方法一 、数组排序方法二、HashMap方法三、摩尔投票法 找出数组中出现次数超过数组长度的一半的数字 方法一 、数组排序 先将数组排序,因为是找出出现次数超过数组长度一半的数字,故在数组中间的数一定是答案,为什么呢?可以举极端的例子,比如经过排序后,这个数字最大,故这个最大的数字组成的相等的区间全部在数组的一侧(从小到大排序在数组右侧,从大到小排序在数组左侧),因为这个数字出现次数超过数组长度的一半,故数组中间那个数,肯定是所求的数字。既然极端的情况符合要

dream_coke的博客 829

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

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

/* copyright@nciaebupt 转载请注明出处 题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。 分析: 1.首先我们想到如果是一个排序好的数组,那么我们只需要遍历一次数组,统计好每个数字出现的次数, 如果大于数组长度的一半就输出这个数字。或者只需要直接输出array[N/2]的值即可。 2.如果是杂乱无章的数据我们可能回想先排序,然后

nciaebupt 2762

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

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

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 一、解题思路 1.定义一个辅助数组 zero ,里面全是0; 2.循环输入的数组 arr ,将 arr 每个位置的值(arr[i])对应到辅助数组zero里的...

weixin_40141473的博客 1883

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 分析:如果有符合条件的数字,则它出现的次数比其他所有数字出现的次数和还要多。在遍历数组时保存两个值:一是数组中一个数字,一是次数。遍历下一个数字时,若它与之前保存的数字相同,...

lyl194458的博客 1764

找出数组中出现次数超过一半的数字

题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。解法一:如果无序,那么我们是不是可以先把数组中所有这些数字先进行排序(至于排序方法可选取最常用的快速排序)。排完序后,直接遍历,在遍历整个数组的同时统计每个数字的出现次数,然后把那个出现次数超过一半的数字直接输出,题目便解答完成了。总的时间复杂度为O(nlogn + n)。但如果是有序的数组呢,或者经过排序把无序的数组变成有序后的...

大雄没有叮当猫的博客 1769

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

剑指offer: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 # -*- coding:utf-8 -*- class Solution: def MoreThanHalfNum_Solution(self, numbers): # write code here # -*- coding:utf-...

weixin_43955099的博客 1108

数组中有一个数字出现的次数超过数组长度的一半

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 情况1: 本题只要求数组中有一个数字出现的次数超过数组长度的一半的情况,所以用相同则加1,不同则减1的原则,最后如果运算的结果>=1,则要检验是否这个数出现的次数的

xieliang0717的博客 1386

数组中出现次数超过一半的数字(JS)

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 function MoreThanHalfNum_Solution(numbers) { let len = numbers.length; let i = ...

Jane_96的博客 1018

找出数组中元素出现次数超过数组长度一半的元素

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 这道题有多种解法,下面主要说两种。 常规方法:创建一个Map,遍历数组中的元素,如果元素不在map中出现过,将元素设置为key,value=1,如果元素在map中,就取出这个元素,并将对应的value值+1.最后遍历map中的元素,如果有value>数组长度的一半,就返回值 思维方

一李 1020
上一篇: 看完这篇session和cookie你就可以招架住面试官了
下一篇: 【define和const常量】以及【new和malloc】的区别
奇幻岛
博客等级 码龄8年 268粉丝 144原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值