题目:Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋
times. The algorithm should run in linear time and in O(1) space.
题意:找到数组中权重大于⌊ n/3 ⌋的数字(成为众数)。
思路:
为了同时满足时间复杂度和空间复杂度,不能用Map来做,根据题意,大于⌊ n/3 ⌋的数字最多不会超过两个,
记变量n1, n2为候选众数; c1, c2为它们对应的出现次数
遍历数组,记当前数字为num
若num与n1或n2相同,则将其对应的出现次数加1
否则,若n1或n2为空,则将其赋值为num,并将对应的计数器置为1
否则,将n1与n2中出现次数较少的数字的计数器减1,若计数器减为0,则将其赋值为num,并将对应的计数器置为1
最后,再统计一次候选众数在数组中出现的次数,若满足要求,则返回之。
代码:
public class Solution { public List<Integer> majorityElement(int[] nums) { List<Integer> list = new ArrayList<Integer>(); if(nums == null || nums.length == 0) return list; int n = nums.length; int count = n/3; int num1 = nums[0]; int num2 = nums[0]; int count1 = 1; int count2 = 0; for(int i = 1 ; i < n ; i++){ int temp = nums[i]; if(temp == num1){ count1++; }else if(temp == num2){ count2++; }else{ if(count2 == 0){ // 最开始 num2 = temp; count2 = 1; continue; } if(count1 < count2){ count1--; }else count2--; if(count1 == 0){ num1 = temp; count1 = 1; } if(count2 == 0){ num2 = temp; count2 = 1; } } } count1 = 0; count2 = 0; for(int i = 0 ; i < n ; i++){ if(nums[i] == num1) count1++; if(nums[i] == num2) count2++; } if(count1 > count) list.add(num1); if(num2 != num1 && count2 > count) list.add(num2); return list; } }
参考链接:http://www.tuicool.com/articles/eA7nIzY