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

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

思路:
方法一:最简单的思路就是将这一组数进行排序,记录下中位数的值,定义一个计数器,遇到和这个数相同的数,就进行加一,最后比较计数器的值与数组长度一半的大小,如果大于就返回中位数的值,如果小于说明不存在返回0。

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int size = numbers.size();
        if(size == 0)
            return 0;

        sort(numbers.begin(), numbers.end());
        int mid = numbers[size/2];

        int count = 0;
        for(int i=0 ;i<size; ++i){
            if(numbers[i]==mid)
                ++count;
        }

        return (count>size/2) ? mid : 0;
    }
};

方法二:也可以借助STL中的容器进行实现,unordered_map存放键值对,一个存放数组中的值,一个记录出现次数。最后遍历进行比较,超过一半,我们就返回其值。

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        if(numbers.empty())
            return 0;

        unordered_map<int, int> res;
        for(int i=0; i<numbers.size(); i++){
            res[numbers[i]]++;
        }

        int size = (numbers.size())/2;
        unordered_map<int, int>::iterator it = res.begin();
        while(it != res.end()){
            if((*it).second > size)
                return (*it).first;
            *it++;
        }
        return 0;
    }
};

方法三:
这种方法,定义了一个time来统计次数,一开始初始化为1,再定义了一个res作为最后的结果。遍历一遍数组,如果下一个数和res相同,time加1;如果time为0,就重新开始计数,time重新记为1;如果下一个数和res不同,time减一。

最后遍历一遍,将res的值与每个值进行比较,如果相等,计数器加一,最后进行比较,如果大于数组个数的一半,就返回res,否则返回0。

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        if(numbers.empty())
            return 0;

        int time = 1;//次数
        int res = numbers[0];
        int size = numbers.size();

        for(int i=1; i<size; i++){
            if(res == numbers[i])
                time++;
            else if(time == 0)//重新开始计数
            {
                res = numbers[i];
                time = 1;
            }
            else
                time--;
        }

        int count = 0;
        for(int i=0 ;i<size; i++){
            if(numbers[i] == res)
                count++;
        }

        return (count*2>size)?res:0;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值