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.
解法1:找中位数,因为出现的次数超过n/2,那么中位数即为majority. 利用快排的思想实现。
class Solution {
public:
int majorityElement(vector<int>& nums)
{
int len = nums.size();
int mid = len/2;
int j = partition(nums,0,len-1);
int start = 0;
int end = len -1;
while(j!=mid)
{
if(j>mid)
{
end = j-1;
j = partition(nums,start,end);
}
if(j<mid)
{
start = j+1;
j = partition(nums,start,end);
}
}
return nums[mid]; // 若下标恰好为mid,则mid左边的数小于num[mid] 右边的数大于等于num[mid] 此时该数为中位数。
}
int partition(vector<int>&data, int start, int end)
{
int index = start;
int small = start - 1;
for (; index <= end; index++)
{
if (data[index] < data[end])
{
small++;
if (small < index)
swap(data[small], data[index]);
}
}
++small;
swap(data[small], data[end]);
return small;
}
};
快排的实现
void sortquick(vector<int> &num,int p,int r)
{
if (p < r)
{
int j = partition(num, p, r);//上面代码中的partition.
sortquick(num, p, j - 1);
sortquick(num, j + 1, r);
}
else
return;
}
可以使用 nth_element(start, start+n, end) 方法代替快排实现
使第n大元素处于第n位置(从0开始,其位置是下标为n的元素),并且比这个元素小的元素都排在这个元素之前,比这个元素大的元素都排在这个元素之后,但不能保证他们是有序的。
class Solution {
public:
int majorityElement(vector<int>& nums) {
nth_element(nums.begin(), nums.begin() + nums.size() / 2, nums.end());
return nums[nums.size() / 2];
}
};
解法2 The hash-table solution
利用unordered_map统计每个出现的元素的个数,一旦个数大于n/2,返回该值。
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int, int> counts;
int n = nums.size();
for (int i = 0; i < n; i++)
if (++counts[nums[i]] > n / 2)
return nums[i];
}
};
解法3:随机法
随机选取一个数字,统计该数字出现的次数,若大于n/2,返回该值。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int n = nums.size();
srand(unsigned(time(NULL)));
while (true) {
int idx = rand() % n;
int candidate = nums[idx];
int counts = 0;
for (int i = 0; i < n; i++)
if (nums[i] == candidate)
counts++;
if (counts > n / 2) return candidate;
}
}
};