【力扣算法】169-求众数

    xiaoxiao2025-03-29  15

    题目

    给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

    你可以假设数组是非空的,并且给定的数组总是存在众数。

    示例 1:

    输入: [3,2,3] 输出: 3

    示例 2:

    输入: [2,2,1,1,1,2,2] 输出: 2

    题解

    无官方题解

    一个方法是HashMap计数,见下面感想部分。巨慢。。。毕竟HashMap的所谓O(1)常数复杂度感觉应该比较大吧,反正最后跑出来和其他方法还是差距挺大的。。。

    还有一个方法是利用排序后众数一定会出现在数组的中间位置的性质。

    执行用时 : 4 ms, 在Majority Element的Java提交中击败了81.73% 的用户

    内存消耗 : 51.1 MB, 在Majority Element的Java提交中击败了20.14% 的用户

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

    这个很好理解,就是众数的定义保证其总个数已经过一半了,所以排序后众数一定经过中间。

    还有就是最快的摩尔投票法了:

    执行用时 : 3 ms, 在Majority Element的Java提交中击败了97.27% 的用户

    内存消耗 : 49.7 MB, 在Majority Element的Java提交中击败了33.97% 的用户

    public static int majorityElement(int[] nums) { int count=0;//计算当前的数字出现的次数 int mj=0;//当前判断的元素 for (int i = 0; i < nums.length; i++) { if(count==0){//当次数为0时,则换下一判断元素 mj=nums[i]; count=1; } else if (nums[i]==mj) { count++;//当前元素等于判断元素,次数加一 } else { count--;//不等于则次数减一 } } return mj; }

    摩尔投票法背后的思想还是挺有意思的,就是整个算法建立在一个性质上:众数稀疏的区域必然对应一个众数密集的区域,非众数即使在众数稀疏的区域暂时存在,但最终在众数密集的区域会被count减至0而被替换;而每个众数每次都能保证和一个其他的数一换一,所以剩下的子数组中的众数仍然是总的数组的众数,且依然满足该性质。

    摩尔投票这种称呼倒是挺新颖的。这个方法感觉之前看到过,但是印象不深。这次不知道能不能记住呢?(不知道这种算法还有啥应用?之前就是在类似这道题的题目中看到这种解法,如果只限于这道题目本身的话,那怪不得我记不住……)

    感想

    自己就是很简单的通过HashMap去计数了,结果感觉又是很慢。最快的方法应该还是摩尔投票法吧。

    执行用时 : 46 ms, 在Majority Element的Java提交中击败了10.85% 的用户

    内存消耗 : 49.7 MB, 在Majority Element的Java提交中击败了34.15% 的用户

    class Solution { public int majorityElement(int[] nums) { HashMap<Integer,Integer> hm = new HashMap<>(); for(int i:nums){ if(hm.containsKey(i)) { if(hm.get(i)+1>nums.length/2) return i; hm.put(i,hm.get(i)+1); } else { if(1>nums.length/2) return i; hm.put(i,1); } } return -1; } }
    最新回复(0)