剑指offer28_数组中出现次数超过一半的数字_题解

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

题目描述

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

示例1

输入

[1,2,3,2,2,2,5,4,2]

返回值

2

分析

方案一:哈希

先遍历一遍数组,在map中存每个元素出现的次数,然后再遍历一次数组,找出众数。

代码

/**
时间复杂度:O(N)
空间复杂度:O(N)
**/
class Solution
{
public:
    int MoreThanHalfNum_Solution(vector<int> numbers)
    {
        unordered_map<int, int> mp;
        for (const int val : numbers)
        {
            mp[val]++;
        }
        for (const int val : numbers)
        {
            if (mp[val] > numbers.size() / 2)
                return val;
        }
        return 0;
    }
};

方案二:排序

将数组排序,众数一定在数组中间,再判断众数出现的次数是否超过数组长度的一半

代码

/**
时间复杂度:O(nlogn)
空间复杂度:O(1)
**/
class Solution
{
public:
    int MoreThanHalfNum_Solution(vector<int> numbers)
    {
        sort(numbers.begin(), numbers.end());
        int cond = numbers[numbers.size() / 2];
        int votes = 0;
        for (const int k : numbers)
        {
            if (cond == k)
                ++votes;
        }
        if (votes > numbers.size() / 2)
            return cond;
        return 0;
    }
};

方案三:摩尔投票法

假设数组首个元素为众数,遍历并统计票数。当发生票数和 = 0时,剩余数组的众数一定不变

算法流程:

  • 初始化: 票数统计 votes = 0 , 众数 x;
  • 循环: 遍历数组 nums 中的每个数字 num ;当 票数 votes 等于 0 ,则假设当前数字 num 是众数;
  • 当 num = x 时,票数 votes 自增 1 ;当 num != x 时,票数 votes 自减 1 ;
  • 返回值: 返回 x 即可;

代码

class Solution
{
public:
    int MoreThanHalfNum_Solution(vector<int> numbers)
    {
        int cond = -1; //众数cond
        int votes = 0; //票数votes
        for (int i = 0; i < numbers.size(); ++i)
        {
            // 当票数votes等于0时,假设当前数字num是众数,投票数+1
            if (votes == 0)
            {
                cond = numbers[i];
                ++votes;
            }
            else
            {
                // 当num=cond时,票数votes++
                if (cond == numbers[i])
                    ++votes;
                // 当num!=cond时,票数votes--
                else
                    --votes;
            }
        }
        votes = 0;
        //验证x是否为众数
        for (const int k : numbers)
        {
            if (cond == k)
                ++votes;
        }
        if (votes > numbers.size() / 2)
            return cond;
        return 0;
    }
};
posted @ 2020-12-31 11:28  RiverCold  阅读(81)  评论(0编辑  收藏  举报