给定一个大小为 n
的数组 nums
,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3] 输出:3
示例 2:
输入:nums = [2,2,1,1,1,2,2] 输出:2
方法一:哈希表
class Solution
{
public:
int majorityElement(vector<int>& nums)
{
unordered_map<int,int> counts;
int majority=0,cnt=0;
for(int num:nums)
{
++counts[num];
if(counts[num]>cnt)
{
majority=num;
cnt=counts[num];
}
}
return majority;
}
};
这段代码定义了一个名为 Solution
的类,其中包含一个名为 majorityElement
的公有成员函数。该函数的目的是找出给定数组 nums
中的众数(即出现次数最多的元素)。
函数分析:
- 函数签名:
int majorityElement(vector<int>& nums)
- 输入参数:
nums
是一个整数类型的向量(vector<int>
),表示输入数组。 - 返回值:函数返回一个整数,表示数组中的众数。
- 输入参数:
- 变量声明:
unordered_map<int,int> counts;
:用于存储每个元素及其出现次数的哈希表。int majority=0,cnt=0;
:majority
用于存储当前的众数,cnt
用于存储当前众数的出现次数。
- 算法逻辑:
- 遍历数组
nums
中的每个元素num
。 - 对于每个元素
num
,在counts
哈希表中增加其计数(++counts[num];
)。 - 如果当前元素
num
的计数大于cnt
,则更新majority
为当前元素num
,并更新cnt
为num
的计数。
- 遍历数组
- 返回值:
- 函数返回
majority
,即数组中的众数。
- 函数返回
算法复杂度分析:
- 时间复杂度:O(n),其中 n 是数组
nums
的长度。因为需要遍历数组中的每个元素。 - 空间复杂度:O(n)。最坏情况下,如果数组中的所有元素都不同,哈希表
counts
将存储 n 个键值对。
方法二:排序
思路
如果将数组 nums 中的所有元素按照单调递增或单调递减的顺序排序,那么下标为 ⌊ 2/n⌋ 的元素(下标从 0 开始)一定是众数。
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size() / 2];
}
};
函数分析
-
排序:
sort(nums.begin(), nums.end());
这行代码将数组nums
进行排序。排序之后,相同的元素会被放在一起。 -
返回中间元素:
return nums[nums.size() / 2];
由于题目保证有一个数出现的次数超过了数组长度的一半,那么在排序后的数组中,这个数必然占据数组中间的位置。因此,返回数组中间的元素即可。
这种解法的时间复杂度是O(nlogn),主要消耗在排序上。空间复杂度是O(logn),这是因为排序算法(如快速排序)通常需要额外的空间来进行递归调用。