题解 | #数组中出现次数超过一半的数字#

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

http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163

题目主要信息:
  • 题目给出一个长度为n的数组,其中有一个数字出现次数超过了数组长度的一半,需要我们找出这个数字
  • 输入数组非空,保证有解,这样就不用考虑特殊情况
举一反三:

学习完本题的思路你可以解决如下题目:

BM52. 数组中只出现一次的两个数字

BM53. 缺失的第一个正整数

方法:哈希表(推荐使用)

知识点:哈希表

哈希表是一种根据关键码(key)直接访问值(value)的一种数据结构。而这种直接访问意味着只要知道key就能在O(1)O(1)时间内得到value,因此哈希表常用来统计频率、快速检验某个元素是否出现过等。

思路:

首先我们分析一下,数组某个元素出现次数超过了数组长度的一半,那它肯定出现最多,而且只要超过了一半,其他数字不可能超过一半了,必定是它。

如果给定的数组是有序的,那我们在连续的相同数字中找到出现次数最多即可,但是题目没有要求有序,一种方法是对数组排序后解决,但是时间复杂度就上去了。那我们可以考虑遍历一次数组统计各个元素出现的次数,找到出现次数大于数组长度一半的那个数字。

具体做法:

  • step 1:构建一个哈希表,统计数组元素各自出现了多少次,即key值为数组元素,value值为其出现次数。
  • step 2:遍历数组,每遇到一个元素就把哈希表中相应key值的value值加1,用来统计出现次数。
  • step 3:本来可以统计完了之后统一遍历哈希表找到频次大于数组长度一半的key值,但是根据我们上面加粗的点,只要它出现超过了一半,不管后面还有没有,必定就是这个元素了,因此每次统计后,我们都可以检查value值是否大于数组长度的一半,如果大于则找到了。

图示:

alt

Java实现代码:

import java.util.*;
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        //哈希表统计每个数字出现的次数
        HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>(); 
        //遍历数组
        for(int i = 0; i < array.length; i++){ 
            //统计频率
            if(!mp.containsKey(array[i]))
                mp.put(array[i], 1);
            else
                mp.put(array[i], mp.get(array[i]) + 1);
            //一旦有个数大于长度一半的情况即可返回
            if(mp.get(array[i]) > array.length / 2) 
                return array[i];
        }
        return 0;
    }
}

C++实现代码:

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        //无序哈希表统计每个数字出现的次数
        unordered_map<int, int> mp; 
        //遍历数组
        for(int i = 0; i < numbers.size(); i++){ 
            //哈希表中相应数字个数加1
            mp[numbers[i]]++; 
            //一旦有个数大于长度一半的情况即可返回
            if(mp[numbers[i]] > numbers.size() / 2) 
                return numbers[i];
        }
        return 0;
    }
};

Python实现代码:

class Solution:
    def MoreThanHalfNum_Solution(self , numbers: List[int]) -> int:
        #无序哈希表统计每个数字出现的次数
        mp = dict() 
        #遍历数组
        for i in range(len(numbers)): 
            if numbers[i] in mp:
                #哈希表中相应数字个数加1
                mp[numbers[i]] += 1  
            else:
                mp[numbers[i]] = 1
            #一旦有个数大于长度一半的情况即可返回
            if mp[numbers[i]] > (int)(len(numbers) / 2): 
                return numbers[i]
        return 0

复杂度分析:

  • 时间复杂度:O(n)O(n),遍历一次数组,哈希表每次操作的复杂度都是O(1)O(1)
  • 空间复杂度:O(n)O(n),最坏情况下n/2+1n/2+1个相同的数字,其他都不同,则共有n/2n/2个不同的数字,哈希表长度需要达n/2n/2
全部评论
题目写了个空间复杂度O(1),你官方就给我来个O(n)
10 回复 分享
发布于 2022-08-01 23:09
比这更可笑的是,代码默认不引入HashMap,他一来就import java.util.*.不借助存储结构就不会解题了是吗?你哪怕抄一下排行榜上的代码我都觉得可行。
点赞 回复 分享
发布于 2022-12-05 20:31 江苏

相关推荐

头像
10-22 20:13
中南大学 Java
序言大家好呀。我是希晨er,一个初入职场的程序猿小登最近上班摸鱼刷到了一篇文章:10年深漂,放弃高薪,回长沙一年有感,还有聊聊30岁大龄程序员过往的心路历程,突然就有点感慨。我如今也做出了和大明哥一样的抉择,只是更早。此外我22年的人生,好像从来没好好记录过。正好现在工作不太忙,就想把这些经历写下来,也希望能得到社区里各位前辈的指点个人背景我是03年出生的西安娃,父母都是普通打工人。刚从中南大学软件工程专业毕业半年,现在在老家的央企过着躺平摆烂的日子成长轨迹从农村到城市的童年我家并不是西安的,只是爸妈在西安上班,从小学之后就把我接到了西安。后来老家房子拆了,爷爷奶奶也搬了过来。农村的生活,我觉...
Yki_:看哭了,恋爱那一段你女朋友说你不够关心她,可你毕竟也愿意遇到矛盾写几千字来和她慢慢分析;说不愿意给她花钱,我感觉可能只是消费观不一样;如果她想留在长沙,也应该提前跟你说开。不过她也许会心疼你放弃大厂offer转向数字马力?我也因为同样的原因有过一段幸福而充满遗憾的感情,不过跟爱情相比确实前途更重要一点。至于offer的选择,换我我也会这么选。把这些旧事记录下来以后,接下来就好好向前看吧,加油兄弟
🍊晨光随笔
点赞 评论 收藏
分享
牛客吹哨人:哨哥晚点统一更新到黑名单:能救一个是一个!26届毁意向毁约裁员黑名单https://www.nowcoder.com/discuss/1525833
点赞 评论 收藏
分享
评论
6
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务