题目
- 给定一个长度为n的数组,找出其中所有出现次数超过n/3的元素
- 要求使用线性时间和常数空间
- 举例输入[3,2,3],输出[3].输入[1,1,1,3,3,2,2,2]输出[1,2]
解题思路
- 求解众数,因为我们要求的是超过n/3的数,假设我们有x个数符合要求,那么每一个x都出现了n/3次,n/3x<=n,那么可解x<=3,但是我们的题意是超过n/3,也就是顶多有两个数超过n/3,剩下一个数肯定小于n/3,也就是众数最多出现两次,x的范围为[0,2]
- 因为题中要求是使用线性时间即是O(n)和常数空间,那么采用HashMap或者排序等方法都不实用了,此时我们只能采用投票算法。
- 在169中采用投票算法计算超过n/2的数据,那么此时计算两个n/3的数据,需要进行两次遍历
,第一次遍历找出两个众数,第二次计算众数出现的次数,因为众数并不是一定存在,所以需要统计出现的次数。找众数就是投票的过程,找出两个出现次数最多的即可
实现代码
class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> result = new ArrayList<>();
//first表示第一个数,second表示第二个数
//cf表示第一个数出现的次数,cs表示第二个数出现的次数
int first = 0, second = 0, cf = 0, cs = 0;
for (int num : nums) {
if (num == first) cf++;
else if (num == second) cs++;
else if (cf == 0) {
first = num;
cf++;
}
else if (cs == 0) {
second = num;
cs++;
}
else {
cf--;
cs--;
}
}
cf = 0;
cs = 0;
for (int num : nums) {
if (num == first) cf++;
else if (num == second) cs++;
}
if (cf > nums.length / 3) result.add(first);
if (cs > nums.length / 3) result.add(second);
return result'
}
}
参考链接
https://www.cnblogs.com/grandyang/p/4606822.html
网友评论