排序后输出中间值:时间复杂度O(nlogn)
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());// c++的数组排序
return nums[nums.size() / 2];
}
};
摩尔投票法 时间复杂度O(n)
链接: 摩尔投票法详解
假设数组的第一个元素为候选人,后面的元素为该候选人投票,若相同则票数count+1,不同则-1,当count=0时则更换候选人,那么多数元素的count必然>0。如下流程:
nums: [7, 7, 5, 7, 5, 1 | 5, 7 | 5, 5, 7, 7 | 7, 7, 7, 7]
candidate: 7 7 7 7 7 7 5 5 5 5 5 5 7 7 7 7
count: 1 2 1 2 1 0 1 0 1 2 1 0 1 2 3 4
有个疑问就是换候选人的时候为什么不是换成初始候选人的下一项而是count=0当前对应的这一项,万一前面漏了跳过了真正的候选人呢?后来看到官方的解释就懂了:
投票法是遇到相同的则 票数 + 1,遇到不同的则 票数 - 1。
且“多数元素”的个数 > ⌊ n/2 ⌋,其余元素的个数总和 <= ⌊ n/2 ⌋。
因此“多数元素”的个数 - 其余元素的个数总和的结果肯定 >= 1。
这就相当于每个 “多数元素” 和其他元素两两相互抵消,抵消到最后肯定还剩余 至少1个“多数元素”。
所以不会抵消完,到最后还是会出现
class Solution {
public:
int majorityElement(vector<int>& nums) {
int max=nums[0];
int count=0;
for(int i=0;i<nums.size();i++){
if(nums[i]==max){
count++;
}
else{
count--;
}
if(count==0){
max=nums[i];
count=1;//出现的第一次也要算进去
}
}
return max;
}
};
哈希表
我们使用哈希映射(HashMap)来存储每个元素以及出现的次数。对于哈希映射中的每个键值对,键表示一个元素,值表示该元素出现的次数。
我们用一个循环遍历数组 nums 并将数组中的每个元素加入哈希映射中。在这之后,我们遍历哈希映射中的所有键值对,返回值最大的键。我们同样也可以在遍历数组 nums 时候使用打擂台的方法,维护最大的值,这样省去了最后对哈希映射的遍历。
下次系统复习哈希表再写,对哈希还是一知半解orz