• LeetCode169. 多数元素


    遍历一遍数组,对所有元素的出现次数做哈希。

    class Solution {
    public:
        int majorityElement(vector<int>& nums) {
            unordered_map<int, int> hash;
            int size = nums.size();
            for(int num : nums) {
                ++hash[num];
                if(hash[num] > size / 2) {
                    return num;
                }
            }
            return 0;
        }
    };
    

    上面的做法时间和空间复杂度都是O(n),这道题还有一个时间复杂度O(n),空间复杂度O(1)的做法。

    我们可以开两个变量,curNum记录当前的(“我们认为的”)出现次数最多的数,cnt记录这个数出现的次数(其实也不完全是这样,继续往下看)

    当cnt大于0的时候,假设我们当前遍历到了一个数nums[i],我们看看nums[i]和curNums是否相同,如果相同,很好,cnt加一,继续看下一个数。

    如果nums[i]和cnt不同,说明出现了一个和(“我们认为的”)出现次数最多的数不同的数,那我们把cnt减一,表示这两个数抵消了。
    然后看一下,这个减一操作之后,cnt是否为0,如果为0,说明我们认为的出现次数最多的数curNum被抵消了,(到目前为止)最起码有和他一样多的数。

    抵消之后,我们再暂且认为现在这个新的数nums[i]是出现次数最多的数,所以把他的值赋给curNum, 然后cnt = 1(因为他现在出现了一次嘛)。

    就一直这样下去,遍历一遍数组之后,curNum记录的就是数组中出现次数超过数组长度一半的数。

    这个算法咋看起来不可思议,为什么这是正确的呢?
    我们可以用反证法,假设数组遍历之后curNum的值不是数组中出现次数超过数组长度一半的数,那说明,真正的在数组中出现次数最多的数(出现次数超过数组长度一半的数)
    被抵消为0了(因为只有被抵消为0的时候才会改变curNum的值),也就说明了数组里最起码有一半的数不同,和题意矛盾,故这个算法是正确的。

    代码如下:

    class Solution {
    public:
        int majorityElement(vector<int>& nums) {
            if(nums.size() == 0) {
                return 0;
            }
            if(nums.size() == 1) {
                return nums[0];
            }
            int curNum = nums[0], cnt = 1;            //最开始我们认为第0个数是出现次数最多的
            for(int i = 1; i < nums.size(); ++i) {
                if(nums[i] == curNum) {               //如果当前的数就是我们认为的最大的数,good,next!
                    ++cnt;
                } else {
                    --cnt;                           //找到了不同的数,抵消一下
                    if(cnt == 0) {                   //抵消为0,我们就该反思一下,maybe我们之前找的数并不是出现次数最大的
                        curNum = nums[i];
                        cnt = 1;
                    }
                }
            }
            return curNum;
        }
    };
    
  • 相关阅读:
    redis学习汇总
    注解配置springMVC
    为什么MYSQL分页时使用limit+ order by会出现数据重复问题
    springMVC请求访问的整个过程
    springMVC项目配置文件
    springMVC三大组件、spring主要jar包、
    单例模式的三种实现方式
    JDBC连接数据库的7个步骤
    数据结构汇总
    Java基础汇总2019
  • 原文地址:https://www.cnblogs.com/linrj/p/13419994.html
Copyright © 2020-2023  润新知