leetcode第169题:多数元素
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
方法一:排序法
因为多数元素的是出现次数大于n/2的元素,所以中间那个元素一定是多数元素
时间复杂度O(nlgn),空间复杂度O(1)
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(),nums.end());
return(nums[nums.size()/2]);
}
};
方法二:哈希表计数法
用哈希表统计每个元素出现的次数,找到出现次数最多的元素
时间复杂度O(n),空间复杂度O(n)
class Solution {
public:
int majorityElement(vector<int>& nums) {
map<int,int>mp;
//统计每个元素出现的次数
for(int i=0;i<nums.size();i++)
mp[nums[i]]++;
//找到出现次数最多的元素
int max=0;
map<int,int>::iterator it;
it=mp.begin();
while(it!=mp.end())
{
if(it->second>mp[max])
max=it->first;
it++;
}
//max为次数最多的元素
return max;
}
};
方法三:摩尔投票法
摩尔投票法:如果下一个元素和当前元素相同,那就相加,否则就相减,减到0就换个数字开始,直到找到一个元素可以抵消不同元素之后count值不为0,这个元素就是最后胜利的元素。
其实就是看作一场战争,有很多很多的国家,每个国家有不同的人口,人和人打架就会同归于尽,如果有一个国家的人口超过了总人口的一半,那他无论怎么打都能打赢,因为一换一它可以换掉所有的人,其他国家怎么打都打不赢,因为他们总会被换掉
时间复杂度:O(n),空间复杂度O(1)
class Solution {
public:
int majorityElement(vector<int>& nums) {
//用candi记录当前的元素,conut记录candi的元素的个数
int candi=nums[0],count=1;
//摩尔投票法
for(int i=1;i<nums.size();i++)
{
if(nums[i]==candi)
count++;
else{
if(count==0)
{
candi=nums[i];
count=1;
}
else
count--;
}
}
//返回两两抵消之后最后胜利的元素
return candi;
}
};
方法四:分治算法
将数组分为左右两个部分,分别找左边和右边的多数元素
class Solution {
public:
int majorityElement(vector<int>& nums) {
return findMajority(nums,0,nums.size()-1);
}
//找多数元素
int findMajority(vector<int>& nums,int start,int end)
{
//递归推出条件,如果只有一个元素,那这个元素就是多数元素
if(start==end)
return nums[start];
//将数组划分为左右两边
int mid=(start+end)/2;
//找到左边的多数元素leftMajority
int left=findMajority(nums,start,mid);
//找到右边的多数元素rightMajority
int right=findMajority(nums,mid+1,end);
//两个数相等,返回左边就好了
if(left==right)
return left;
//统计左边多数元素出现的次数
int leftCount=0;
for(int i=start;i<=mid;i++)
{
if(nums[i]==left)
leftCount++;
}
//统计右边多数元素出现的次数
int rightCount=0;
for(int i=mid+1;i<=end;i++)
{
if(nums[i]==right)
rightCount++;
}
//找左右两边的多数元素出现次数的较大值,这个数就是多数元素
return leftCount>rightCount?left:right;
}
};