求众数

从今天开始做LeetCode的题目啦,先从简单的开始,同时也开始学习Java。

先从求众数这道题开始吧:求众数-力扣

 

我最开始的想法是用暴力法:

class Solution {
    public int majorityElement(int[] nums) {
        double n = nums.length;
        double temp=1.0;
        if(n==1)
        {
            return nums[0];
        }
        
        for(int i=0;i<nums.length;i++)
        {
            temp=1;
           for(int j=i+1;j<nums.length;j++)
           {
               if(nums[j]==nums[i])
                   temp++;
           }
            if(temp>=n/2)
                return nums[i];
        }

        return 0;
    }
}

思路就是穷举,找到出现次数超过一半的数输出,时间复杂度:O(n^2),用了964 ms,远远超过其他人用的时间= =

 

接着试着用Map来做:

class Solution {
    public int majorityElement(int[] nums) {
        Map<Integer, Integer>map=new HashMap<>();
        double n=nums.length;
        for(int i=0;i<nums.length;i++)
        {
            if(map.containsKey(nums[i]))//不存在该数字
            {
                map.put(nums[i],map.get(nums[i])+1);
                if(map.get(nums[i])>n/2)
                {
                    return nums[i];
                }
                
            }
            else
            {
                map.put(nums[i],1);
            }
        }
        return nums[0];
    }
}

这次时间降低的比较多,只用了50 ms,但是发现还是比不过大多数人的算法,于是我点开时间分布来看别人的算法,发现了几个更好的算法,贴在下面:

 

排序:进行排序之后,因为众数本身出现次数超过整体一半的特性,一定会出现在 n/2 处,开销主要来自快排

class Solution {
    public int majorityElement(int[] nums) {
    Arrays.sort(nums);
        return nums[nums.length/2];
    }
}

 

摩尔投票算法:执行时间1ms,时间复杂度:O(n)的神奇算法!看评论有人说是消消乐,太形象了,就是利用众数本身出现次数超过整体1/2,如果把众数记为 +1,把其他数记为 -1,抵消之后肯定大于0,则运用计数器count和一个记录变量,记录下最后一个count > 0的数字就可以了,代码如下:

class Solution {
    public int majorityElement(int[] nums) {
        int candi = 0, count = 0;
        for (int i : nums) {
            if (count == 0) {
                count = 1;
                candi = i;
            } else {
                if (i == candi) count++;
                else count--;
            }
        }
        return candi;
    }
}

此算法也可以延伸到其他考虑出现频率大于某一界限的题目上。

 

posted @ 2019-09-04 14:33  dtokeyc  阅读(303)  评论(0编辑  收藏  举报