169_求众数(Majority-Element)

这道题有 5 种方法,8 种实现,详细分析可以看花花酱YouTube 专栏

描述

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

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

示例 1:

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

示例 2:

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

解法一:暴力法

思路

遍历数组中的每个元素,统计该元素出现的次数(嵌套遍历),如果该元素出现的次数 \(> \left \lfloor n/2 \right \rfloor\),则该元素就是数组的众数。

Java 实现

class Solution {
public int majorityElement(int[] nums) {
int majorityCount = nums.length / 2;
for (int num1 : nums) {
int count = 0;
for (int num2 : nums) {
if (num2 == num1) {
++count;
}
}
if (count > majorityCount) {
return num1;
}
}
throw new IllegalArgumentException("The array does not contain a majority element!");
}
}

Python 实现

class Solution:
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
majority_count = len(nums) // 2
for num1 in nums:
count = sum(1 for num2 in nums if num2 == num1)
if count > majority_count:
return num1

复杂度分析

  • 时间复杂度:\(O(n^2)\),其中 \(n\) 表示数组的长度,由于嵌套了两层 for 循环,因此总的时间复杂度是 \(O(n^2)\) 的
  • 空间复杂度:\(O(1)\)

解法二:哈希表

思路

利用哈希表记录数组中元素出现的次数,由于哈希表的插入操作的时间复杂度是 \(O(1)\) 的,所以遍历整个数组统计出现次数的操作的时间复杂度是 \(O(n)\) 的。接着,再遍历一遍哈希表,取出众数。

Java 实现

class Solution {
public int majorityElement(int[] nums) {
Map<Integer, Integer> counts = new HashMap<>();
for (int num : nums) {
if (counts.containsKey(num)) {
counts.replace(num, counts.get(num) + 1);
} else {
counts.put(num, 1);
}
} Map.Entry<Integer, Integer> majorityEntry = null;
for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) {
majorityEntry = entry;
}
} return majorityEntry.getKey();
}
}

Python 实现

class Solution:
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
counts = dict()
for num in nums:
counts[num] = counts.get(num, 0) + 1
return max(counts, key=counts.get)

复杂度分析

  • 时间复杂度:\(O(n)\),其中 \(n\) 为数组的长度。由于哈希表中元素的数目最多为 \(n - \left( \left \lfloor n/2 \right \rfloor + 1 \right) + 1 = n - \left \lfloor n/2 \right \rfloor\),因此遍历一次哈希表最多需要 \(n - \left \lfloor n/2 \right \rfloor\) 次操作,而遍历一遍数组需要 \(n\) 次操作,所以总的时间复杂度是 \(O(n)\) 的
  • 空间复杂度:\(O(n)\),因为哈希表最多需要保存 \(n - \left \lfloor n/2 \right \rfloor\) 个元素

解法三:排序

将数组按照顺序(递增或者递减)排列好后,索引为 \(\left \lfloor n/2 \right \rfloor\) 的元素就是数组的众数。

Java 实现

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

Python 实现

class Solution:
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return sorted(nums)[len(nums) // 2]

复杂度分析

  • 时间复杂度:\(O(n \log(n))\),其中 \(n\) 表示数组的长度,对数组进行排序的时间复杂度为 \(O(n \log(n))\) 的
  • 空间复杂度:\(O(n)\) 或者 \(O(1)\),取决于是否可以直接对原数组直接进行排序,如果不允许的话,需要额外的空间复制数组

解法四:随机选择【待完成】

思路

Java实现

Python 实现

复杂度分析

解法五:分而治之(Divide and conquer)【待完成】

思路

Java 实现

Python 实现

复杂度分析

解法六:多数投票算法(Boyer-Moore majority vote algorithm)

思路

多数投票算法一般用于寻找一个序列的多数元素(只需要线性时间和常数空间),是一种典型的流式算法(streaming algorithm)。但是,一般来说,该算法无法找到一个序列的众数(mode),除非众数出现的次数大于 \(\lfloor n/2 \rfloor\) 次。多数投票算法的思想是这样:统计一个序列中的所有元素,将多数元素记为 \(+1\),其余的元素记为 \(-1\),那么最后的和一定是正的。具体地,该算法会维护两个变量,一个用于记录序列中的元素,记为 m,一个作为计数器,记为 count。遍历数组中的每个元素,如果当前的 count 为 0,则将当前元素保存在 m 中,并设 count 为1;如果 count 不为0,则判断当前元素与 m 是否相等,相等则 count 加一,不等则 count 减一。遍历结束,变量 m 就是我们寻找的多数元素。

Java 实现

class Solution {
public int majorityElement(int[] nums) {
int me = nums[0], count = 1;
for (int i = 1; i < nums.length; ++i) {
if (count == 0) {
me = nums[i];
count = 1;
} else if (me == nums[i]) {
++count;
} else {
--count;
}
}
return me;
}
}

Python 实现

class Solution:
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
me, count = 0, 0
for num in nums:
if count == 0:
me, count = num, 1
elif me == num:
count += 1
else:
count -= 1
return me

复杂度分析

  • 时间复杂度:\(O(n)\),其中 \(n\) 表示数组的长度
  • 空间复杂度:\(O(1)\)

【LeetCode题解】169_求众数(Majority-Element)的更多相关文章

  1. [Swift]LeetCode169. 求众数 | Majority Element

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  2. 【leetcode刷题笔记】Majority Element

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  3. leetCode题解之求二叉树每层的平均值

    1.题目描述 Given a non-empty binary tree, return the average value of the nodes on each level in the for ...

  4. leetCode题解之求二叉树最大深度

    1.题目描述 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along t ...

  5. Leetcode题目169.求众数(简单)

    题目描述: 给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在众数. 示例 1: 输入: [3,2,3] ...

  6. Leetcode题解 - 双指针求n数之和

    1. 两数之和 """ 双指针,题目需要返回下标,所以记录一个数字对应的下标 """ class Solution: def twoSum( ...

  7. [LeetCode] Majority Element II 求众数之二

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...

  8. Leetcode之分治法专题-169. 求众数(Majority Element)

    Leetcode之分治法专题-169. 求众数(Majority Element) 给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是 ...

  9. [LeetCode] Majority Element 求众数

    Given an array of size n, find the majority element. The majority element is the element that appear ...

随机推荐

  1. WP8.1 中获取背景色和主题色

    背景色: Application.Current.RequestedTheme 返回的值是一个枚举,Light 或者 Dark. 主题色: public static Color GetPhoneAc ...

  2. Python学习-30.Python中的元组(tuple)

    元组使用()定义,元组一旦定义就无法修改. 元组的索引方式同列表,也是使用[]. 元组也可以进行切片操作,使用方式同列表一样. 可以说,一个没法修改的列表就是元组. 在没有修改操作的情况下,应尽可能使 ...

  3. .Net core 应用程序发布Web时,有些文件夹没有发布成功解决办法

    如果文件是你在项目中手动添加的, 那么在解决方案中右击文件,然后点击属性,文件属性----高级----复制到输出目录----改为始终复制/如果较新则复制 即可.

  4. wpf 右下角弹出窗

    自己写的wpf 弹出框,欢迎拍砖,动画都写在了后台代码,前台代码不太重要,用了一下iconfont,具体样式我就不贴出来了,本次主要是后台代码的动画 需要有父级窗口才可以使用. 前台代码: <W ...

  5. sqlServer 查询表中31到40的记录,考虑id不连续的情况

    SQL   查询表中31到40的记录,考虑id不连续的情况 写出一条sql语句输出users表中31到40记录(数据库为SQL Server,以自动增长的ID作为主键,注意ID可能不是连续的)? -- ...

  6. 【ZOJ2314】Reactor Cooling(有上下界的网络流)

    前言 话说有上下界的网络流好像全机房就我一个人会手动滑稽,当然这是不可能的 Solution 其实这道题目就是一道板子题,主要讲解一下怎么做无源无汇的上下界最大流: 算法步骤 1.将每条边转换成0~u ...

  7. vhosetuser 和 vhostuservlient 差异

    Open vSwitch支持的vHost-user类型 在Open vSwitch中vHost User通过socket进行通信,模式为client-server,其中server端负责创建/管理/销 ...

  8. Python(多进程multiprocessing模块)

    day31 http://www.cnblogs.com/yuanchenqi/articles/5745958.html 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分 ...

  9. jQuery Validation Plugin

    使用方式很简单,简单测试代码如下: <html> <head> <script type="text/javascript" src="./ ...

  10. 解决org.hibernate.QueryException illegal attempt to dereference collection 异常错误

    今天做项目的时候,有两个实体:款式.品牌两者关系是多对多的关联关系,实现的功能是:通过选择款式,显示出该款式的所有品牌.HQL语句如下: 运行时出现这个异常错误:org.hibernate.Query ...