vector<int> a
a.size()//容器a内元素个数
sort(a.begin(),a,end())//升序排序a
a.push_back(i)//向容器加入元素
a.pop_back()//弹出容器顶部元素
a.empty()//判空
169. 多数元素
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3]
输出:3
示例 2:
输入:nums = [2,2,1,1,1,2,2]
输出:2
排序+查找
class Solution {
public:
int majorityElement(vector<int>& nums) {
long long int n = nums.size();
long long int p = n/2;
long long int i,j,k = 0;
sort(nums.begin(),nums.end());//排序
for(i = 0;i < n;)
{
k = 0;
for(j = i;j < n &&nums[j] == nums[i];j++)
k++;
if(k > p)
break;
i = j;
}
return nums[i];
}
};
排序+规律
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size() / 2];
}
};
//作者:力扣官方题解
//链接:https://leetcode.cn/problems/majority-//element/solutions/146074/duo-shu-yuan-su-by-leetcode-solution/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
随机化
class Solution {
public:
int majorityElement(vector<int>& nums) {
while (true) {
int candidate = nums[rand() % nums.size()];
int count = 0;
for (int num : nums)
if (num == candidate)
++count;
if (count > nums.size() / 2)
return candidate;
}
return -1;
}
};
//作者:力扣官方题解
//链接:https://leetcode.cn/problems/majority-element/solutions/146074/duo-shu-yuan-su-by-leetcode-solution/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Boyer-Moore 投票算法
比如:
【1,1,2,2,2】
public int majorityElement(int[] nums) {
int winner = nums[0];
int count = 1;
for (int i = 1; i < nums.length; i++) {
if (winner == nums[i]) {
count++;
} else if (count == 0) {
winner = nums[i];
count++;
} else {
count--;
}
}
return winner;
}
Boyer-Moore 投票算法进阶
229. 多数元素 II
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
示例 1:
输入:nums = [3,2,3]
输出:[3]
示例 2:
输入:nums = [1]
输出:[1]
示例 3:
输入:nums = [1,2]
输出:[1,2]
摩尔投票法分为两个阶段:抵消阶段和计数阶段
抵消阶段:两个不同投票进行对坑,并且同时抵消掉各一张票,如果两个投票相同,则累加可抵消的次数;
计数阶段:在抵消阶段最后得到的抵消计数只要不为 0,那这个候选人是有可能超过一半的票数的,但这不意味着这个候选人的票数一定能超过一半,例如 [A, B, C] 的抵消阶段,最后得到的结果是 [C,1],C 候选人的票数也未能超过一半的票数。为了验证,则需要遍历一次,统计票数,才可确定。
绿色的小人去选出在三个人中选出红色的候选人
三个小人中产生最多两个候选人,即最多有两个人在数组中出现的次数大于1/3,必定有一个人的出现次数小于1/3.
在投票环节中:
(1)三个人都有一票等于,三个人都没有票,两个候选人票数减1
(2)一个候选人有票,另外一个没有,则此时被投票的当候选人
比如:ABBCBCAA
最开始投票给了A,B两人:
cand1 = A count1 = 1
cand2 = B count2 = 1
接下来又是B:
cand1 = A count1 = 1
cand2 = B count2 = 2
接下来是C:
cand1 = A count1 = 0//三个人都有一票等于,三个人都没有票,两个候选人票数减1
cand2 = B count2 = 1
接下来B:
cand1 = A count1 = 0
cand2 = B count2 = 2
C://A没票了,C当候选人
cand1 = C count1 = 1
cand2 = B count2 = 2
A:
cand1 = C count1 = 0
cand2 = B count2 = 1
A:
cand1 = A count1 = 1
cand2 = B count2 = 1
代码如下:
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
vector<int> a;
//投票阶段
//选出候选人
int i,n = nums.size();
int cand1 = 0,cand2 = 0;//候选人
int count1 = 0,count2 = 0;//此候选人所得票数
for(i = 0;i < n;i++)
{
if(nums[i] == cand1)
count1 ++;
else if(nums[i] == cand2)
count2 ++;
else if(count1 != 0 && count2 != 0)//三个人都有一票
{
count1--;
count2--;
}
else if(count1 == 0)//cand1没有票
{
cand1 = nums[i];
count1 = 1;
}
else if(count2 == 0)//cand2没有票
{
cand2 = nums[i];
count2 = 1;
}
}
//计数阶段
int q = n/3;
int cnt1 = 0,cnt2 = 0;
for(i = 0;i < n;i++)
if(nums[i] == cand1)
cnt1++;
else if(nums[i] == cand2)
cnt2++;
if(count1!=0&&cnt1 > q)
a.push_back(cand1);
if(count2!=0&&cnt2 > q)
a.push_back(cand2);
return a;
}
};
如果最开始把cand1 = nums[0],cand2 = nums[1]
[3,3,4]会没法通过,因为两个候选人重复了