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

来源:互联网 发布:淘宝联盟电脑版 编辑:程序博客网 时间:2024/05/01 01:00

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

方法一

思路:

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

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

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


下标 i012345times101010Array[i]123451result112244       下标 i012345times101212Array[i]121151result111111


实现代码:

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

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

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

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



0 0
原创粉丝点击