Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.(给定一个大小为n的数组,找出majority element,majority element是指在数组中出现超过n/2次的元素)
You may assume that the array is non-empty and the majority element always exist in the array.(假设数组是非空的,并且majority element总是存在的)
1.个人分析
思路:
(1)从头到尾遍历数组,统计每个不同元素在数组中的个数,找出个数大于n/2的元素。
(2)先将数组进行排序,显然排序后的数组中相同元素都相邻排列,然后统计不同元素的个数,最后找出个数大于n/2的元素。
2.个人解法
int majorityElement(vector<int>& nums)
{
int counterLen = nums.size();
int *counter = new int[counterLen];
for(int i=0; i<counterLen; ++i)
counter[i] = 0;
int key;
for (int i=0; i<counterLen; ++i)
{
key = nums[i] % counterLen;
if(key < 0)
key += counterLen;
++counter[key] ;
if(counter[key] > (counterLen/2))
return nums[i];
}
return -1;
}
结果显示能够通过所有测试用例,时间和空间复杂度都为O(n),只不过这里要注意当进行哈希散列过程中key为负数的情况,教材给出的处理方法是key=key + tableSize。
3.参考解法
(1)
int majorityElement(vector<int>& nums) {
int winner = 0;
for (int i=0; i<32; i++) {
int ones = 0;
for (int n : nums)
ones += (n >> i) & 1;
winner += (ones > nums.size() / 2) << i;
}
return winner;
}
这种解法涉及到位运算
(2)
int majorityElement(int[] num) {
int major=num[0], count = 1;
for(int i=1; i<num.length;i++){
if(count==0){
count++;
major=num[i];
}else if(major==num[i]){
count++;
}else count--;
}
return major;
}
上面解法是Java实现的,可能是所有方法里最快的,记得该方法是来源自一篇学术论文中的成果,但是自己还不理解其实现的原理。
4.总结
看了这道题其他人给出的各种解法后,发现算法的水非常深,只有你想不到,没有实现不了更快更简洁的方法。
PS:
- 题目的中文翻译是本人所作,如有偏差敬请指正。
- 其中的“个人分析”和“个人解法”均是本人最初的想法和做法,不一定是对的,只是作为一个对照和记录。