前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >剑指Offer题解 - Day51

剑指Offer题解 - Day51

作者头像
chuckQu
发布2022-08-19 11:04:26
1770
发布2022-08-19 11:04:26
举报
文章被收录于专栏:前端F2E

剑指 Offer 39. 数组中出现次数超过一半的数字

力扣题目链接[1]

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

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

「示例 1:」

代码语言:javascript
复制
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

「限制:」

1 <= 数组长度 <= 50000

思路:

如果说,将数组进行排序,那么出现次数超过一半的数字肯定位于数组的中位数。

中位数

代码语言:javascript
复制
/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let result = nums.sort((a, b) => a - b) // 排序
    return result[Math.floor(nums.length / 2)] // 获取中位数
};

分析:

本方法是最简单易懂的方法,但是直接使用API来题解不能达到出题者的目的。因此还需要寻找更优解。

哈希表

同样的,我们可以用哈希表来存储每个数字出现的次数,然后找出出现次数最多的即可。该方法的时间复杂度和空间复杂度均为O(n)

摩尔投票法

该方法的原理是票数的正负抵消。从而获取到出现次数超过一半的数字。

首先寻找规律,首先称出现次数超过一半的数字为 「众数」

  • 如果是众数则投票 「+1」 ,如果不是众数则投票 「-1」 ,最后的结果一定 「大于0」
  • 如果数组的前面部分数字的票数和为 「0」 ,则剩余数字的票数和一定 「大于0」,并且众数依旧不变 ****;

根据上述两条规律,可以根据投票数为 「0」 不断缩小数组的范围,最终剩余的数字就是 「众数」

代码语言:javascript
复制
/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let res = 0; // 初始化众数为0
    let votes = 0; // 初始化投票数为0
    for (const num of nums) {
        if (votes === 0) res = num; // 当投票数为0时,假设当前元素就是众数
        votes += num === res ? 1 : -1; // 投票
    }
    return res; // 返回众数
};
  • 时间复杂度 O(n)。
  • 空间复杂度 O(1)。

分析:

核心思路是:当投票数为0时,假设当前元素就是众数。然后根据投票规则进行投票:如果是众数则投票 「+1」 ,如果不是众数则投票 「-1」

当下次遇到投票数为 「0」 时,前面所有的元素就可以丢弃了,因为这意味着众数还在剩余元素里面。此时继续假设当前元素为众数,执行投票的逻辑。

直到遍历完数组,最终的结果res就是众数。然后返回res即可。

由于需要遍历整个数组,因此时间复杂度是O(n),声明常数级别的变量占用O(1)的空间。

总结

本题既可以排序取中位数,又可以通过哈希表统计出现次数。效率最高的办法是第三种:投票法。通过正负抵消的方式,最终留下来的就是众数。

参考资料

[1]力扣题目链接: https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/99iy4g/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端F2E 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 剑指 Offer 39. 数组中出现次数超过一半的数字
    • 中位数
      • 哈希表
        • 摩尔投票法
          • 总结
            • 参考资料
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档