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

如题,若存在超过一半长度的数字,返回它,反之则返回0(这种返回并不好,但是为了简化问题和说明思想)

方法一

思路:

1)从头开始遍历数组,用一个标记位times=1开始,用一个变量来记录候选的值result,初始化为数组第一个数字;当遍历时遇见相同的则times加1,不同的就减1,若times==1,则更新result 为当前遍历的值。

2)原理:试想,如果刚好有一个数等于长度的一半,那么times加和减的次数相等,最后为0;当大于长度的一半,则加的次数大于减的次数,这个输就是最后一次把times设为1对应的记录数;若出现次数最多的一个数小于长度一半,则减的数目大于加的数目。

3)下图中用Array表示数组,times为标记数,当前候选值result。第一次让times变为1的记录就是要找的。


下标 i012345
times101010
Array[i]123451
result112244
       
下标 i012345
times101212
Array[i]121151
result111111


实现代码:

int MoreThanHalfNum_Solution(vector<int> numbers) {
        
        int len = numbers.size();
        if(len<1) return 0;
       //------------------------------------- 
        int result = numbers[0];
        int times = 1;
        for(int i = 1; i<len;++i)
        {
            if(0==times)
                {
                    result = numbers[i];
                    times = 1;
           		 }
            else if(numbers[i] == result)
                	++times;
            else
               	    --times;
        }
        //-------------------------------------
        //-----判断是否有数字超过数组长度的一半------
    	int numtimes  = 0;
        for(int i=0;i<len;++i)
           {if(numbers[i]==result)
            numtimes++;
           }
        if(numtimes*2<=len)
            return 0;
        //-------------------------------------
        return result;

    }
-------------------------------------------------------------------

方法二

当然还有很多方法,再介绍一种实用的方法,既然某数字出现的次数超过了数组长度的一半,那么考虑将数组进行排序,则中间位置的数就是我们要找的

1)排序,可以自己写,也可以利用标准库中的sort()函数,在#include<algorithm.h>中。

2)取中间位置的数字,就是所求。

3)问题是如何判断是否存在这样的一个数字。那么可以在中间位置的数向两边扩展,求连续相等的数子的长度判断该长度是否大于总长度的一半。

具体代码就不写了,思路已经清晰,如果要求不能用标准库函数,则难点在于写排序算法。参考我总结的排序算法:

《那些必须要知道的排序算法

-----------------------------------------------------------------



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值