题目地址:力扣
解法1:排序
显然,因为目标值超过数组长度的一半,那么只需返回排序之后中间的结果即可
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size()/2];
}
};
解法2:Boyer-Moore 投票算法
算法名字听起来听唬人的,但是思想非常简单。假设两个不同的数可以两两抵消,那么剩下来的数必然是目标值。
但是这个思想在实际编码的时候需要考虑一下实现问题。我们可以这样,首先把数组的第一个数设为目标值,并且给它一个计数器。然后往后遍历,如果碰到的相同值,那么计数器自增;如果碰到的不同值,那么就计数器自减(相当于抵消过程)。当计数器减到0的时候,重新选择后面一个作为目标值,并把计数器重新置为1。只需要遍历到数组末尾,目标值存储的就是我们要找的那个多数元素。
class Solution {
public:
int majorityElement(vector<int>& nums) {
// 计数器和目标值初始化
int cnt = 1;
int target = nums[0];
// 迭代器从第二个位置开始
auto it = nums.begin() + 1;
// 只要没迭代到数组末尾
while (it != nums.end())
{
// 目标值等与当前遍历的值,计数器自增,迭代器往后走
if (target == *it++)
++cnt;
// 目标值不等于当前遍历的值,计数器自减
else
{
--cnt;
// 若计数器为0了,那么重新选定目标值(注意前面迭代器已经往后走了一次)
// 并且迭代器再往后走,计数器置为1
if (cnt == 0)
{
target = *it++;
cnt = 1;
}
}
}
// 遍历完返回目标值即可
return target;
}
};
Accepted
- 43/43 cases passed (12 ms)
- Your runtime beats 91.21 % of cpp submissions
- Your memory usage beats 96.05 % of cpp submissions (18.9 MB)