leetcode 面试经典 150 题:多数元素
链接 | 多数元素 |
---|---|
题序号 | 169 |
题型 | 数组 |
解法 | 1. 排序法、2. Boyer-Moore投票算法 |
难度 | 简单 |
熟练度 | ✅✅✅✅✅ |
题目
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3]
输出:3示例 2:
输入:nums = [2,2,1,1,1,2,2]
输出:2提示:
n == nums.length
1 <= n <= 5 * 104
-109 <= nums[i] <= 109进阶:
尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
题解
排序法
- 核心要点:先排序,下标n/2的位置一定是多数元素,复杂度根据排序算法的复杂度来。
- 复杂度:排序算法的时间复杂度通常是 O(n log n),其中 n 是数组的长度。这意味着对于大型数组,排序方法可能比 Boyer-Moore 投票算法慢,后者的时间复杂度为 O(n)。
- c++ 实现算法:
//排序法
class Solution2 {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return (nums[nums.size()/2]);
}
};
Boyer-Moore投票算法
- Boyer-Moore投票:Boyer-Moore投票算法是一种用于在数组中找出出现次数超过一半的元素(即多数元素)的高效算法。这个算法由Robert S. Boyer和J Strother Moore于1981年提出。算法的核心思想是通过两次遍历数组的过程来找出多数元素。
- 核心要点:该题适合使用Boyer-Moore投票算法,即在一个序列中找出一个出现次数超过n/2的元素(如果存在的话)。
- 复杂度:时间复杂度 O(n), 空间复杂度 O(1)
- c++ 实现算法:
class Solution {
public:
int majorityElement(vector<int>& nums) {
int count = 0;
int candidate = 0;
for(int i = 0; i < nums.size(); i++){
if(count == 0){
candidate = nums[i];
}
count += (candidate == nums[i]) ? 1 : -1;
}
return candidate;
}
};
- 推演:
-
假设我们有一个数组 nums = [3, 2, 3]:
-
初始化:count = 0,candidate = 0。
-
遍历 nums[0] = 3:
count 为0,所以将 nums[0] 设为 candidate,即 candidate = 3,count = 1。 -
遍历 nums[1] = 2:
nums[1] 与 candidate 不同,count 减1,count = 0。 -
遍历 nums[2] = 3:
count 为0,所以将 nums[2] 设为 candidate,即 candidate = 3,count = 1。 -
遍历结束后,candidate = 3,这是数组中的多数元素。
完整demo
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
int majorityElement(vector<int>& nums) {
int count = 0;
int candidate = 0;
for(int i = 0; i < nums.size(); i++){
if(count == 0){
candidate = nums[i];
}
count += (candidate == nums[i]) ? 1 : -1;
}
return candidate;
}
};
//排序法
class Solution2 {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return (nums[nums.size()/2]);
}
};
int main(){
vector <int> nums = {3, 2, 3};
Solution2 solution;
int element = solution.majorityElement(nums);
cout << "major elemet: " << element << endl;
return 0;
}