LeetCode 169-多数元素

106 阅读1分钟

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

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

示例 1:

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

示例 2:

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

提示: n == nums.length 1 <= n <= 5 * 104 -109 <= nums[i] <= 109

思路 : 使用排序

如果将数组 nums 中的所有元素按照单调递增或单调递减的顺序排序,那么下标为[n/2]的元素(下标从 0 开始)一定是众数。

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

复杂度分析

时间复杂度:O(nlogn)。将数组排序的时间复杂度为 O(nlogn)。

空间复杂度:O(logn)。如果使用语言自带的排序算法,需要使用 O(logn)的栈空间。如果自己编写堆排序,则只需要使用 O(1]的额外空间。

进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。

摩尔投票法思路

候选人(cand_num)初始化为nums[0],票数count初始化为1。

当遇到与cand_num相同的数,则票数count = count + 1,否则票数count = count - 1。

当票数count为0时,更换候选人,并将票数count重置为1。

遍历完数组后,cand_num即为最终答案。

为何这行得通呢?

投票法是遇到相同的则票数 + 1,遇到不同的则票数 - 1。

且“多数元素”的个数> ⌊ n/2 ⌋,其余元素的个数总和<= ⌊ n/2 ⌋。

因此“多数元素”的个数 - 其余元素的个数总和 的结果 肯定 >= 1。

这就相当于每个“多数元素”和其他元素 两两相互抵消,抵消到最后肯定还剩余至少1个“多数元素”。

无论数组是[1 2 1 2 1],亦或是[1 2 2 1 1],总能得到正确的候选人。

class Solution {
    fun majorityElement(nums: IntArray): Int {
        var count = 1
        var cand_num = nums[0]
        for(i in 1 until nums.size){
            if(cand_num == nums[i]){
                ++count 
            }else{
                if(--count == 0){
                    cand_num = nums[i]
                    count = 1
                }
            }
        }
        return cand_num
    }
}