给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
map
class Solution {
public:
int majorityElement(vector<int>& nums) {
map<int,int> mp;
for(int i=0;i<nums.size();i++)
{
mp[nums[i]]+=1;
if(mp[nums[i]]>nums.size()/2)
return nums[i];
}
return -1;
}
};
排序法
因为大于一半的数,所有数组中心位置必然是众数。
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size() / 2];
}
};
随机法
因为众数占一半,所以随机找一个数大概率是要找的众数,赌就完事了
class Solution {
public:
int majorityElement(vector<int>& nums) {
srand(time(NULL));
while(1)
{
int n=nums.size();
int ans=0;
int re=nums[rand()%n];
for(int nu:nums)
if(nu==re)
ans++;
if(ans>n/2)
return re;
}
}
};
分治法
每一次把区间分为两部分,分别寻找两个区间(0,mid),(mid+1,n-1)的众数a和b,要寻找的众数T必定在这两个众数其一,此处可用反证法:如果T不是两个区间的众数,那么T的次数<(0,mid)区间的一半,也小于(mid+1,n-1)的一半,那么T的次数一定小于(0,n)的一半,意味T不是(0,n)区间的众数,与题意矛盾,所以T一定是两个区间之一的众数。
class Solution {
public:
int choose(vector<int>& nums,int n,int le,int ri)
{
int ans=0;
for(int i=le;i<=ri;i++)
{
if(nums[i]==n)
ans++;
}
return ans;
}
int majority_element_rec(vector<int>& nums,int le,int ri)
{
if(le==ri)
return nums[le];
int mid=(le+ri)/2;
int left_rec=majority_element_rec(nums,le,mid);
int right_rec=majority_element_rec(nums,mid+1,ri);
if(choose(nums,left_rec,le,ri)>(ri-le+1)/2)
return left_rec;
if(choose(nums,right_rec,le,ri)>(ri-le+1)/2)
return right_rec;
return -1;
}
int majorityElement(vector<int>& nums) {
return majority_element_rec(nums,0,nums.size()-1);
}
};
Boyer-Moore 投票算法
(1)字面理解就是候选人是众数,所以给他投票的人是最多的,赞成票肯定大于反对票,最终众数胜出。
(2)投票算法个人思路,数组中众数和其他数分成几队人在一个擂台上打架,每次擂台随机上一队的人,
如果擂台没人则留在擂台上当擂主等待挑战者;
如果是同队则一起留在擂台上;
如果不是一队的人,就干一架,因为打的比较狠,挑战者和擂台上一个人一起被抬下去;
最后,因为众数人多,所以最后站在擂台上的擂主一定是众数队,众数,永远滴神!
同时可以发现其他队不懂团结,他们的内斗消耗更有利于众数获胜(队内成员不用全部上擂台就已经没有挑战者了);
假设极端情况下数组只有两种数,众数队n+1,另一数n-1,1换1也不够打的,众数队依然可以在擂台上站到最后。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int champoin=-1;
int people=0;
for(int challenger:nums)
{
if(challenger==champoin)
people++;
else
{
people--;
if(people<0)
{
people=1;
champoin=challenger;
}
}
}
return champoin;
}
};