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.
思路:Leetcode里面给的标签是Array
,Divide and Conquer
, 和Bit Manipulation
。所以我们先考虑Hash Table
,Bit manipulation
, Divide and Conquer
这三种方法。
1、Hash Table: 用unordered_map
记录每个nums[i]
出现的次数,只要某一个nums[i]
出现的次数大于 ⌊ n/2 ⌋
次,就返回。代码如下:
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int, int> map;
int major;
for (int i = 0; i < nums.size(); ++i){
if(++map[nums[i]] > nums.size() / 2)
major = nums[i];
}
return major;
}
};
2.Bit Manipulation
思路是:既然某一个数nums[i]
出现的次数大于 ⌊ n/2 ⌋
次,那么它所对应的二进制数在每一个bit(无论nums[i]
对应的值是0
或者1
)上出现的次数也一定大于 ⌊ n/2 ⌋
次。例如,假设某一个bit位上nums[i]
对应的值是0,那么nums这个数组的每个数,依次跟这一位是1而其他位上全部是0的mask进行与
运算,一共出现的count数一定不会超过⌊ n/2 ⌋
;假设某一个bit位上nums[i]
对应的值是1,那么nums这个数组的每个数,依次跟这一位是1而其他位上全部是0的mask进行与
运算,一共出现的count数一定超过⌊ n/2 ⌋
。因此,只要count数超过⌊ n/2 ⌋
,就把 major
(初值为0)跟mask做 或
操作,这样就可以还原major
在这个二进制位上的值。最终,32位依次操作完,我们就得到了major。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int major = 0;
for(int i = 0, mask = 1; i < 32; i++, mask <<= 1){
int count = 0;
for(int j = 0; j < nums.size(); ++j){
if(nums[j] & mask)
count++;
if(count > nums.size() / 2){
major = major | mask;
break;
}
}
}
return major;
}
};
3.Divide and Conquer
代码如下:
class Solution {
public:
int majorityElement(vector<int>& nums) {
return majority(nums, 0, nums.size());
}
private:
int majority(vector<int>& nums, int left, int right){
if(nums[left] == nums[right]) return nums[left];
int mid = left + (right - left) / 2;
int lm = majority(nums, left, mid);
int rm = majority(nums, mid + 1, right);
if(lm == rm) return lm;
return count(nums.begin(), nums.end(), lm) > count(nums.begin(), nums.end(), rm) ? lm : rm;
}
};
4.Sorting 先按照大小排序,返回nums[nums.size() / 2]即可。
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size() / 2];
}
};
也可以用c++ STL的 nth_element
, 直接排序前nums.size() / 2
个数即可
class Solution {
public:
int majorityElement(vector<int>& nums) {
nth_element(nums.begin(), nums.begin() + nums.size() / 2, nums.end());
return nums[nums.size() / 2];
}
};
5.Moore Voting Algorithm
简单来说,基本思路是: If we cancel out each occurrence of an element e
with all the other elements that are different than from e
, then e
will exist till the end, if it is a major element.
代码如下:
class Solution {
public:
int majorityElement(vector<int>& nums) {
int major = 0, counts = 0, n = nums.size();
for(int i = 0; i < n; ++i){
if(counts == 0){
major = nums[i];
counts = 1;
}
else
counts+= (nums[i] == major)? +1 : -1;
}
return major;
}
};