剑指offer-数组中出现次数超过一半的数字(c++ 多种方法)

这是一篇关于如何在C++中找到数组中出现次数超过一半的数字的博客。介绍了三种方法:1)排序后搜索法,通过对数组排序来确定目标数字;2)排序后的中位数法,利用中位数特性找到目标数字;3)对抗法,通过正负计数对抗找到最终存活的数字。文章适合面试准备和经验分享。

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

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

题解:
根据题目要求,可以通过多种方法进行测试。
1)排序—搜索法
首先对数组进行排序,相同数字位于连续的位置。因此,计算每个数字出现的次数,如果超过一半,则退出遍历,输出结果。若未超过一般,则计数重置为0,数字修改为下一数字。
代码如下:

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int res=0;
        if(numbers.size()==0) return res;
        if(numbers.size()==1) return numbers[0];
        sort(numbers.begin(),numbers.end());
        int half=numbers.size()/2;
        int temp=numbers[0];
        int cnt=0;
        for(int i=0;i<numbers.size();i++){
            if(numbers[i]==temp)
                cnt++;
            if(numbers[i]!=temp){
                if(cnt<=half){
                    cnt=1;
                    temp=numbers[i];
                }
                else{
                    res=temp;
                    break;
                }
            }
        }
        return res;
    }
}

2)排序-中位法:
将数组进行排序,如果存在一个数字出现的次数是超过一半的,那么位于数组中间位置的数则必定是该数字,得到数字后,在进行遍历,若该数出现的次数超过长度一半,则输出。

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int res=0;
        if(numbers.size()==0) return res;
        if(numbers.size()==1) return numbers[0];
        sort(numbers.begin(),numbers.end());
        int half=numbers.size()/2;
        int temp=numbers[half];
        int cnt=0;
        for(int i=0;i<numbers.size();i++){
            if(numbers[i]==temp)
                cnt++;
            if(numbers[i]>temp){
                if(cnt>half){
                    res=temp;
                    break;
                }
                else break;
            }
        }
        return res;*/
    }
};

3)对抗法:
存在一个数出现次数超过数组长度的一半,那么若进行出现次数对抗(即若出现一个相同的数+1,不相同的数-1。出现次数为0时,将该位置的数重新作为对抗数),若存在对抗数,那么最终存活下来的数必定是该数。但,若刚好等于该数的一半次数。如长度为9,出现次数为4,则该数便不是。
代码如下:

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int res=0;
        if(numbers.size()==0) return res;
        if(numbers.size()==1) return numbers[0];
        int temp;
        int cnt=0;
        for(int i=0;i<numbers.size();i++){
            if(cnt==0){
                temp=numbers[i];
                cnt=0;
            }
            if(numbers[i]==temp) cnt++;
            else if(numbers[i]!=temp) cnt--;
        }
        cnt=0;
        for(int i=0;i<numbers.size();i++)
            if(numbers[i]==temp)cnt++;
        if(cnt>numbers.size()/2)
            res=temp;
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值