剑指offer学习笔记——面试题29:数组中出现次数超过一半的数字

题目描述

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

解题思路:

看到这到题第一时间有两个思路,第一个思路是进行排序,那么如果一定存在这样的一个数的话,最中间的数即为所求!但是排序的复杂度为O(nlogn),有点慢。

第二个思路就是对元素计数,相当于借助哈希表。这样一来时间复杂度为O(N),空间复杂度也为O(N)

int MoreThanHalfNum_Solution(vector<int> numbers) {
        unordered_map<int,int> m;     //Hash表
        int len = numbers.size();
        for(int i=0;i<len;i++)
            m[numbers[i]]++;
        for(auto &it:m)
            if(it.second>len/2)
                return it.first;
        return 0;
    }

第三种方法比较巧妙,在不借助额外空间的情况下,时间复杂度也为O(N):

    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int len = numbers.size();
        int times = 1;
        int res = numbers.front();   //记res为主元元素
        for(int i=0;i<len;i++)
        {
            if(times==0)      
            {
                res = numbers[i];     //选取新的数字作为主元元素
                times = 1;
            }
            else
            {
                if(res==numbers[i])    //相等则+1
                    times++;
                else                   //否则-1
                    times--;
            }
        }
        times = 0;
        for(auto &n:numbers)
            if(n==res)
                times++;            //重新记录主元元素的个数
        if(times>len/2)             //如果符合要求,则找到了主元元素
            return res;
        return 0;
    }

猜你喜欢

转载自blog.csdn.net/super_gk/article/details/80869807
今日推荐