刷LeetCode100道-Day07

179.多数元素

题目

给定一个大小为 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

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

想法

可以用一个mp存放,如果这个值没出现就存进去,如果出现了就+1,如果值超过了数组长度的一半就直接返回

实现

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let map = new Map()
    for(let i = 0;i < nums.length;i ++){
        if(map.has(nums[i])){
            let times = map.get(nums[i])
            map.set(nums[i], times+1)
            if((times + 1) > (nums.length / 2)) return nums[i]
        }else{
            map.set(nums[i], 1)
        }
    }
    return nums[0]
};

同样的思想,别人写的优雅多了

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let halft = nums.length / 2;
    let map = new Map;
    for(let num of nums){
        if(map.has(num)){
            let currNum = map.get(num);
            map.set(num, currNum + 1)
        }else{
            map.set(num, 1)
        }
        if(map.get(num) > half) return num;
    }
};

其他

看了题解,除了我上面用的是计数法,还有两种解法

排序法

排好序之后,按照题目的规则 ,它一定出现在中间列,向下取整就可以

nums.sort((a,b)=> a - b)
return nums[Math.floor(nums.length / 2)]

摩尔投票法

这几个是在题解评论区复制过来的,觉得是精髓

思想一

核心思想--抵消原则:
在一个数组中,如果某个元素的出现次数超过了数组长度的一半,那么这个元素与其他所有元素一一配对,最后仍然会剩下至少一个该元素。
通过“投票”和“抵消”的过程,可以逐步消除不同的元素,最终留下的候选人就是可能的主要元素。

思想二

候选人(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个 “多数元素”。

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let cand_num = nums[0], count = 0;
    for(let i = 0; i < nums.length; i ++){
        if(count == 0){
            cand_num = nums[i]
        }
        if(cand_num == nums[i]){
            count ++;
        }else {
            count --;
        }
    }
    return cand_num
};

这个方法是满足题目要求的时间复杂度O(n) , 空间复杂度O(1)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。