LeetCode 算法:主要元素

776 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

主要元素

原题地址

数组中占比超过一半的元素称之为主要元素。给你一个 整数 数组,找出其中的主要元素。若没有,返回 -1 。请设计时间复杂度为 O(N) 、空间复杂度为 O(1) 的解决方案。

示例 1:

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

示例 2:

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

示例 3:

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

思路分析

方法一

  1. 排除题目中的时间复杂度和控件复杂度的要求,可以很迅速的解答本题;
  2. 使用一个 obj 来存储数组中每个元素出现的次数;
  3. 然后遍历 objkey,来寻找对应的 value 值大于 nums.lengh / 2 的 元素,最后返回对应的 key(即数组中的元素)即可;
  4. 若遍历过后没有符合条件的可以返回,那么返回 -1

方法二

  1. 定义一个 res 以及一个 countcount 用来统计次数,res 用来记录数组中的元素;
  2. 在经过一轮循环后可以得到一个次数最多的 res 值;
  3. 然后,再次循环来统计下 res 出现的次数,循环之前重置 count 值,记录到 count 上即可;
  4. 最后再判断,count 是否大于数组长度的一半,否则返回 -1

[1,2,5,9,5,9,5,5,5] 为例,看下经过一轮循环后,得到的 res 值以及 count 值:

indexrescount
011
110
251
351
450
551
650
752
853

AC 代码

方法一

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    const len = nums.length
    const obj = {}
    for(let i = 0; i < len; i++) {
        if(obj[nums[i]]) {
            obj[nums[i]] += 1
        } else {
            obj[nums[i]] = 1
        }
    }
    const keys = Object.keys(obj)
    for(let i = 0; i < keys.length; i++) {
        if(obj[keys[i]] > len / 2) {
            return keys[i]
        }
    }
    return -1
};

结果:

  • 执行结果: 通过
  • 执行用时:80 ms, 在所有 JavaScript 提交中击败了12.03%的用户
  • 内存消耗:43.4 MB, 在所有 JavaScript 提交中击败了22.79%的用户
  • 通过测试用例:46 / 46

方法二

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let res = null
    let count = 0
    for (let i = 0; i < nums.length; i ++) {
        if (count === 0) {
            res = nums[i]
            count = 1
        } else if (res === nums[i]) {
            count ++
        } else {
            count --
        }
    }
    count = 0
    for (let i = 0; i < nums.length; i ++) {
        if (nums[i] === res) {
            count++
        }
    }
    return count > (nums.length / 2) ? res : -1
};

结果:

  • 执行结果: 通过
  • 执行用时:55 ms, 在所有 JavaScript 提交中击败了97.08%的用户
  • 内存消耗:42.2 MB, 在所有 JavaScript 提交中击败了89.88%的用户
  • 通过测试用例:46 / 46

END