给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
cpp
#include <vector>
class Solution {
public:
int majorityElement(std::vector<int>& nums) {
int candidate = nums[0];
int count = 1;
for (int i = 1; i < nums.size(); ++i) {
if (nums[i] == candidate) {
// 如果当前元素与候选元素相同,则计数器加一
++count;
} else {
// 如果当前元素与候选元素不同,则计数器减一
--count;
// 当计数器变为 0 时,重新选择候选元素
if (count == 0) {
candidate = nums[i];
count = 1;
}
}
}
// 经过上述遍历后,候选元素就是多数元素
return candidate;
}
};
int main() {
std::vector<int> nums = {3, 2, 3};
Solution solution;
int majority = solution.majorityElement(nums);
return 0;
}
可以使用摩尔投票算法(Boyer-Moore Voting Algorithm)来解决这个问题,在遍历数组时,维护一个候选元素和一个计数器。初始时,候选元素设为数组的第一个元素,计数器设为 1。然后从数组的第二个元素开始遍历,如果当前元素与候选元素相同,则计数器加一,否则计数器减一。当计数器减为 0 时,重新选择候选元素为当前元素,并将计数器重置为 1。最终选出的候选元素就是多数元素。
这个算法的精髓在于,在遍历过程中,如果存在多数元素,它的出现次数一定比其他所有元素的出现次数之和还要多。因此,候选元素的出现次数减去其他非候选元素的出现次数,最终结果一定大于 0。
对于时间复杂度和空间复杂度的分析:
时间复杂度:算法只需要对数组进行一次线性遍历,因此时间复杂度为 O(n),其中 n 是数组的长度。
空间复杂度:算法只需要常数级别的额外空间用于存储候选元素和计数器,因此空间复杂度为 O(1)。