牛客剑指Offer面试题39:数组中出现次数超过一半的数字

题目描述

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

思路

总述:
若已知给定为指针,则需判断是否为nullptr;另外数组出现次数最多的数字可能并未达到数组长度的一半,需最后判断(checkMoreThanHalf函数)

代码可有两种思路:
1.基于Partition函数(快排关键函数),但会修改输入的数组,如面试官不允许则不能使用此方法
2.(代码使用,首选,不修改输入的数组)遍历数组时保存2个值(数组中的数字,出现的次数times)
遍历至下一个数字时:
如数字相同,times++;
如数字相异,times–;
如次数times=0时,保存下一个数字,且将times=1,继续遍历.
最后判断数组中出现次数最多的数字是否大于数组长度的一半(checkMoreThanHalf函数)

注意:
1.vector的size()函数返回类型为size_type,如需在循环中用到数组长度,则需前面int length = vector.size(),方可比较

代码

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        //判断有效性
        if(numbers.empty())
            return 0;
        //初始化数字 和 次数
        int result = numbers[0];
        int times = 1;
        int length = numbers.size();
        //逐个遍历所有数字,找到出现频率最高的数字result
        for(int i = 1; i < length; ++i)
        {
            //次数为0,保存下一个数字,并统计次数
            if(times == 0)
            {
                times = 1;
                result = numbers[i];
            }
            //找到相同数字,次数++
            else if(numbers[i] == result)
                times++;
            //数字相异,次数--
            else
                times--;
        }
        //判断出现频率最高的数字result的出现次数是否超过数组的一半
        if(!checkMoreThanHalf(numbers, result, length))
            return 0;
        return result;
    }
    
private:
    bool checkMoreThanHalf(vector<int> numbers, int result, int length)
    {
        //设定是否超过一半的标识
        bool isMoreThanHalf = false;
        //设定指定数字出现的次数
        int resultTimes = 0;
        //遍历数组统计result出现次数
        for(int i = 0; i < length ; ++i)
        {
            if(numbers[i] == result)
                resultTimes++;
        }
        
        if(resultTimes * 2 > length)
            isMoreThanHalf = true;
        return isMoreThanHalf;
    }
};
发布了65 篇原创文章 · 获赞 0 · 访问量 2045

猜你喜欢

转载自blog.csdn.net/ljmiiianng/article/details/103718339
今日推荐