在一个数组中找到主要的元素,也就是出现次数大于数组长度一半的元素。
容易想到的方式就是计数,出现次数最多的就是majority element,其次就是排序,中间的就是majority element。
但是还有两种更有意思的实现方式时间效率O(n),空间效率O(1):
1、Moore voting algorithm 投票算法,因为符合要求的majority element总是存在的,所以首先置计数器count=1,并选择数组的第一个元素作为candidate,往后遍历并计数,与candidate相同则count++,不同则count--,当count=0则选择数组中的下一个数作为candidate,遍历结束candidate则为majority element。
public int majorityElement(int[] num) { int count = 1; int candidate = num[0]; for (int i = 1; i < num.length; i++) { if (count == 0) { candidate = num[i]; } if (num[i] == candidate) { count++; } else { count--; } } return candidate; }
2、这种方式挺有意思。因为majority element出现的次数大于 ⌊ n/2 ⌋ 次,而题目中给的是int类型数组,对于每一个数字的32位,majority element的每一位是相同的,所以不管这一位是1或0,出现次数多的总是majority element的。
下面之所以用C++的方式来实现,是因为在用Java来写的过程中出现了个问题就是Math.pow(a,b)来计算幂次的时候结果是double类型,强转之后丢失一半,所以还要处理这个情况比较麻烦,用C++来没有出现这个问题。
class Solution { public: int majorityElement(vector<int> &num) { int bitCnt[32]; memset(bitCnt, 0, sizeof(bitCnt)); for (int i = 0; i < num.size(); i++) { for (int j = 0; j < 32; j++) { if (num[i] & (1 << j)) bitCnt[j]++; } } int ans = 0; for (int i = 0; i < 32; i++) { if (bitCnt[i] > num.size()/2) ans += (int)pow(2, i); } return ans; } };
时间: 2024-10-25 17:51:22