problems:
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
You may assume that the array is non-empty and the majority element always exist in the array.
Example 1:
Input: [3,2,3]
Output: 3
Example 2:
Input: [2,2,1,1,1,2,2]
Output: 2
tips:
这道题意在求解出现次数最多的元素.
solutions:
1.暴力求解:思路很简单,遇到一次加1,但是细节很多,比如全局变量的归零等.
class Solution {
public:
int majorityElement(vector<int>& nums) {
int n = nums.size();
int count = 0;//当前元素的次数
int coun = 0;//最多次数
int tt = 0;//出现次数最多的元素值
int flag = 0;//标志位
vector<int> nn;//存储已经出现过的元素
if(n == 1)
{
return nums[0];
}
else
for(int i = 0;i < n;i++)
{
int t = nums[i];
for(int k = 0;k<nn.size();k++)//判断当前元素是否已经求解过
{
if(t == nn[k])
{
flag = 1;
break;
}
}
if(flag==0)//表示第一次遇到这个数
{
nn.push_back(t);
count = 1;//第一次计数
for(int j = i+1;j<n;j++)
{
if(t == nums[j]) count++;//开始计数
}
if(count > coun)//判断出现次数最多的值
{
tt = t;
coun = count;
}
}
flag = 0;//记得要清0
}
return tt;
}
};
2.使用哈希表的方式:unordered_map.每个关键字只出现一次(对应每个元素),关键字的值对应其出现的次数.
class Solution {
public:
int majorityElement(vector<int>& nums) {
int n = nums.size();
int t;
if(n == 1)
{
t= nums[0];
}
else
{
unordered_map<int,int> mm;//这里可以使用unordered_map(在c++11标准库中)不可以使用hash_map
for(auto val:nums)//c++11新特性,范围for,处理每个字符
{
++mm[val];
}
for(auto val:mm)
{
if(val.second > n/2)
t=val.first;
}
}
return t;
}
};
3.摩尔投票法:
前提是有且只有一个数的数量超过总数的一半.
(代码参考博客园Grandyang,对该方法的理解参考知乎 https://www.zhihu.com/question/49973163/answer/617122734)
很形象的一种解释:摩尔投票法的核心就是对拼消耗.假设玩一个诸侯争霸的游戏,假设你方人口超过总人口一半以上,并且能保证每个人口出去干仗都能一对一同归于尽。最后还有人活下来的国家就是胜利。那就大混战呗,最差所有人都联合起来对付你(对应你每次选择作为计数器的数都是众数),或者其他国家也会相互攻击(会选择其他数作为计数器的数),但是只要你们不要内斗,最后肯定你赢。最后能剩下的必定是自己人.很有画面感吧,只要有一方人口过半,不论怎么打,只要一致对外肯定有剩余.
在代码中就是:当计数器为0时,将当前的元素设置为超半数的值,计数器加一,当下一个元素与当前大多数不同时计数器减一(对拼,消耗一对),若相同则计数器加一.
class Solution {
public:
int majorityElement(vector<int>& nums) {
int res =0;//代表大多数
int count = 0;//代表计数器
for(auto num : nums)
{
if(count == 0)
{
res = num;
count++;
}
else
{
(res == num) ? count++ : count--;
}
}
return res;
}
};