【面试经典】多数元素

news/2024/12/28 8:07:41/

链接:169. 多数元素 - 力扣(LeetCode)

解题思路:

在本文中,“数组中出现次数超过一半的数字” 被称为 “众数” 。

需要注意的是,数学中众数的定义为 “数组中出现次数最多的数字” ,与本文定义不同。

本题常见的三种解法:

1.哈希表统计法: 遍历数组 nums ,用 HashMap 统计各数字的数量,即可找出 众数 。此方法时间和空间复杂度均为 O(N) 。
2.数组排序法: 将数组 nums 排序,数组中点的元素 一定为众数。
3.摩尔投票法: 核心理念为 票数正负抵消 。此方法时间和空间复杂度分别为 O(N) 和 O(1) ,为本题的最佳解法。


摩尔投票:

设输入数组 nums 的众数为 x ,数组长度为 n 。

推论一: 若记 众数 的票数为 +1 ,非众数 的票数为 −1 ,则一定有所有数字的 票数和 >0 。

推论二: 若数组的前 a 个数字的 票数和 =0 ,则 数组剩余 (n−a) 个数字的 票数和一定仍 >0 ,即后 (n−a) 个数字的 众数仍为 x 。

根据以上推论,记数组首个元素为 n1,众数为 x ,遍历并统计票数。当发生 票数和 =0 时,剩余数组的众数一定不变 ,这是由于:

当 n1 = x : 抵消的所有数字中,有一半是众数 x 。
当 n1 != x : 抵消的所有数字中,众数 x 的数量最少为 0 个,最多为一半。
利用此特性,每轮假设发生 票数和 =0 都可以 缩小剩余数组区间 。当遍历完成时,最后一轮假设的数字即为众数。

算法流程:

1.初始化: 票数统计 votes = 0 , 众数 x。
2.循环: 遍历数组 nums 中的每个数字 num 。
        当 票数 votes 等于 0 ,则假设当前数字 num 是众数。
        当 num = x 时,票数 votes 自增 1 ;当 num != x 时,票数 votes 自减 1 。
3.返回值: 返回 x 即可。

class Solution {public int majorityElement(int[] nums) {int x = 0, votes = 0;for (int num : nums){if (votes == 0) x = num;votes += num == x ? 1 : -1;}return x;}
}

复杂度分析:

  • 时间复杂度 O(N) : N 为数组 nums 长度。
  • 空间复杂度 O(1) : votes 变量使用常数大小的额外空间。

拓展:

由于题目说明“给定的数组总是存在多数元素”,因此本题不用考虑 数组不存在众数 的情况。若考虑,需要加入一个 “验证环节” ,遍历数组 nums 统计 x 的数量。

若 x 的数量超过数组长度一半,则返回 x 。
否则,返回未找到众数。

class Solution {public int majorityElement(int[] nums) {int x = 0, votes = 0, count = 0;for (int num : nums){if (votes == 0) x = num;votes += num == x ? 1 : -1;}// 验证 x 是否为众数for (int num : nums)if (num == x) count++;return count > nums.length / 2 ? x : 0; // 当无众数时返回 0}
}

时间复杂度和空间复杂度都不变,仍为 O(N) 和 O(1) 。


http://www.ppmy.cn/news/1558739.html

相关文章

mybatis-plus自动填充时间的配置类实现

mybatis-plus自动填充时间的配置类实现 在实际操作过程中,我们并不希望创建时间、修改时间这些来手动进行,而是希望通过自动化来完成,而mybatis-plus则也提供了自动填充功能来实现这一操作,接下来,就来了解一下mybatis…

第1章 R语言中的并行处理入门

标准:时间,开发,运行,工具,R机器,多核。 rdsm,openmp,conda。 相互网页外链。 第一章 1.1 反复出现的主题: 良好并行所具有的标准 R(解释性语言)的核心操作都在语言内部进行了高效的实现,因而只要正确使用&#xff…

自动驾驶AVM环视算法--python版本的车轮投影模式

c语言版本和算法原理的可以查看本人的其他文档。《自动驾驶AVM环视算法--超广角模式/转向模式/3D碗型投影模式/窄边模式/车轮模式等的实现》本文档进用于展示部分代码的视线,获取方式网盘自行获取(非免费介意勿下载):链接: https:…

1-Linux 基础入门指南

Linux 基础入门指南:历史、发行版与基础操作 一、Linux 简介 Linux 是一个开源且免费的操作系统内核,由芬兰计算机科学家林纳斯托瓦兹(Linus Torvalds)于1991年首次发布。这个操作系统基于Unix设计哲学,但与商业Unix版本不同的是,Linux是完全开放源代码的,这意味着任何…

PyPika:Python SQL 查询构建器

什么是 PyPika? Pypika 是一个 Python 库,用于构建 SQL 查询。它提供了一种简洁、直观的方式来生成 SQL 语句,而无需手动编写复杂的 SQL 代码。Pypika 的设计哲学是尽可能地接近 SQL 的自然语法,同时利用 Python 的强大功能来简化…

golang 并发--goroutine(四)

golang 语言最大的特点之一就是语法上支持并发,通过简单的语法很容易就能创建一个 go 程,这就使得 golang 天生适合写高并发的程序。这一章节我们就主要介绍 go 程,但是要想完全理解 go 程我们需要深入研究 GPM 模型,关于 GPM 模型…

移植 OLLVM 到 Android NDK,Android Studio 中使用 OLLVM

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ OLLVM、LLVM 与 Android NDK 在 Android NDK 中,LLVM/Clang 是默认的编译器。自 Android NDK r18 开始,Google 弃用了 GCC&#xff0c…

UE5 把场景转成HDR图

目录 使用影片渲染队列 使用影片渲染队列 以下方法实测 UE5.4 有效 1.打开影片渲染队列窗口。依次打开:窗口—过场动画—影片渲染队列 2.添加Sequence动画。点击“渲染”按钮,选择要渲染的Sequence。 3.设置输出配置。 点击“Unsaved Config”打开配置…