【LeetCode题解】169_求众数(Majority-Element)
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)的更多相关文章
- [Swift]LeetCode169. 求众数 | Majority Element
Given an array of size n, find the majority element. The majority element is the element that appear ...
- 【leetcode刷题笔记】Majority Element
Given an array of size n, find the majority element. The majority element is the element that appear ...
- leetCode题解之求二叉树每层的平均值
1.题目描述 Given a non-empty binary tree, return the average value of the nodes on each level in the for ...
- leetCode题解之求二叉树最大深度
1.题目描述 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along t ...
- Leetcode题目169.求众数(简单)
题目描述: 给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在众数. 示例 1: 输入: [3,2,3] ...
- Leetcode题解 - 双指针求n数之和
1. 两数之和 """ 双指针,题目需要返回下标,所以记录一个数字对应的下标 """ class Solution: def twoSum( ...
- [LeetCode] Majority Element II 求众数之二
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...
- Leetcode之分治法专题-169. 求众数(Majority Element)
Leetcode之分治法专题-169. 求众数(Majority Element) 给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是 ...
- [LeetCode] Majority Element 求众数
Given an array of size n, find the majority element. The majority element is the element that appear ...
随机推荐
- [ACM_数据结构] 线段树模板
#include<iostream> #include<cmath> using namespace std; #define maxn 200005 class Node{ ...
- LeetCode136:Single Number
题目: Given an array of integers, every element appears twice except for one. Find that single one. No ...
- WinFrom下Webbrowser加载自定义页面的技巧
先使用Navigate("about:balnk")方法,打开一个空页面,实际内容在IE_DocumentCompleted中写入.代码来源于csdnreader程序. priva ...
- 第二章 ConcurrentHashMap源码解析
注:在看这篇文章之前,如果对HashMap的层不清楚的话,建议先去看看HashMap源码解析. http://www.cnblogs.com/java-zhao/p/5106189.html 1.对于 ...
- Day 32 网络编程
一.网络协议基础篇 一台完整的计算机由硬件.系统.软件组成,具备这三个条件,计算机就可以运行,但是只能自己和自己玩.为了实现计算机和计算机间的连接,就需要借助互联网,如全世界人类交流将英语作为标准语言 ...
- ko内核模块文件以及载入模块命令modprobe insmod
原文链接:https://blog.csdn.net/evenness/article/details/7655921?utm_source=blogxgwz5 modprobe: Load modu ...
- LCS2 - Longest Common Substring II(spoj1812)(sam(后缀自动机)+多串LCS)
A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...
- 萝卜保卫战3内购破解+Toast窗口增加(Love版)
涉及到一些不同的破解的方法,以及不同的破解思路,还有一些重要权限的删除等. 作者:HAI_ 这次目标是经常玩的萝卜保卫战,不知不觉,已经更新到3了.详细分析请参考https://bbs.ichunqi ...
- Windows下的Nginx安装与配置(PHP)
因为一直用Apache作为服务器,对Apache的使用和配置已经相对熟悉,今天换了一下nginx的服务器,整个配置流程相对比较简单,php的配置没有任何变化. 主要的参考文档为 http://blog ...
- SQL 高效的万能分页存储过程
代码如下: USE [Blog] IF OBJECT_ID('Proc_Paging', 'P') IS NOT NULL --删除同名存储过程 DROP PROC Proc_Paging GO CR ...
