GRE回归,响应老师号召,做分治题目。
题目:
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.map直接记录每个数有几个,找出现次数最大的就可以了。
整个算法复杂度是O(nlogn)
#include <map>
class Solution {
public:
int majorityElement(vector<int>& nums) {
map<int, int> mp;
int sz = nums.size();
for (int i = 0; i < sz; i++) {
mp[nums[i]]++;
if (mp[nums[i]] > sz / 2) return nums[i];
}
return 0;//这个必须要写,否则CE,不明觉厉
}
};
2.排序
根据题目叙述,保证存在majority element,所以排序后位于数组的中间的数一定是majority element。
算法复杂度仍然是O(nlogn)
代码就略了。
3.位运算
这个我一开始没往位运算这方面想,不过无意发现了Tags里有bit manipulation,所以才想到的。
一个数在数组中出现了超过n/2次,则这个数字的每一位必然在他的位置上出现超过n/2次。
所以对每一位统计1多还是0多就可以了。
这个比map还慢主要是因为常数太大了,当数组很大的时候才能体现这种算法的优势。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int one, zero;
int sz = nums.size();
int ans = 0;
for (int i = 0; i < 32; i++) {
one = 0;
zero = 0;
for (int j = 0; j < sz; j++) {
if (nums[j] & (1 << i)) one++;
else zero++;
}
if (one > zero) ans = ans | (1 << i);
}
return ans;
}
};