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

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

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

描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。你可以假设数组是非空的,并且给定的数组总是存在多数元素。

1<=数组长度<=50000,0<=数组元素<=10000

示例1

输入:
[1,2,3,2,2,2,5,4,2]

返回值:
2

示例2

输入:
[3,3,3,3,2,2,2]

返回值:
3

示例3

输入:
[1]

返回值:
1

思路

这道题是让找出数组中数量最多的数,最直观的解法就是将数组排好序,然后取中位数即可。但是这么做并不是最优解,接下来有一种办法能在O(n)的时间复杂度内解决这道题。

  1. 定义一个计数器count;用于存储结果的 res。count 用来标识这个字符串是否是超过一半的那个字符串;res 用来存储最终结果。
  2. 咱们开始遍历数组,当 count = 0时,说明前面并没有找到出现次数最多的那个字符串,那么就把当下的字符串 str 暂定为最终的结果,count = 1;res = str。
  3. res 和 遍历到的 str 字符串不相等时,看看 count 是否大于 0,如果大于 0 ,则说明 res 是前面出现次数最多的那个字符串,当前的 str 抵消一次 count, count --;
  4. res 和 遍历到的 str 字符串相等时,说明前面 str 和前面出现次数最多的字符串一致,count ++。

AC 代码

    public int MoreThanHalfNum_Solution(int [] array) {
        int count = 0;
        int res = 0;
        for (int x : array) {
            // 等于 0,说明前面没有找到数量最多的数,从新开始计数
            if (count == 0) {
                res = x;
                count ++;
            } else if (res == x) {
                // 相等时,累加即可
                count ++;

            } else {
                // 不相等时,先判断前面是否选出数量最多的数,选出来就 --
                if (count > 0) {
                    count --;
                } else {
                    // 没有选出来酒用当下的数
                    res = x;
                }
            }
        }
        // 返回最终结果
        return res;
    }
  • 时间复杂度:O(n),n 为数组长度。
  • 空间复杂度:O(1)。

最后

大家可以去 【牛客网-题库-在线编程】去练习一下。
可以去微信搜索:【蘑菇睡不着】交个朋友~
也可以扫描下方二维码。

图片说明

AC_算法题 文章被收录于专栏

AC 算法题

全部评论

相关推荐

下北泽:都是校友,还是同届,我就说直白点,不委婉了,我相信你应该也不是个玻璃心,首先你觉得一个双非的绩点写简历上有用吗?班长职务有用吗?ccf有用吗?企业会关心你高数满分与否吗?第二,第一个项目实在太烂,一眼就能看出是外卖,还是毫无包装的外卖,使用JWT来鉴权,把热点数据放进Redis这两个点居然还能写进简历里,说难听点这两个东西都是学个几十分钟,调用个API就能完成的事情,在双非一本的条件下,这种项目你觉得能拿出手吗,第二个项目你写的东西和你的求职方向有任何的匹配吗?第三,计设那一块毫无价值,如果想突出自己会前端,直接写入专业技能不行吗,最后,专业技能里像深入理解JVM底层原理这种你觉得这句话你自己真的能匹配吗?都是校友加上同届,我措辞直接,但希望能点出你的问题,想进大厂还得继续沉淀项目和学习
点赞 评论 收藏
分享
高斯林的信徒:武大简历挂?我勒个骚岗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务