题目:
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.
题意:
这题是之前的那题的升华,首先这类题是不能用排序来做的,因为已经写了时间复杂度为O(1),所以如果采用排序算法,最好的情况也是O(nlogn)的情况,所以我们必须想一种另类的方法,这里就是由一种叫做摩尔投票法的方法来做。这种类型的题目,首先要分析最多有几个可能的情况会出现,首先针对此题,我们发现,因为题目中已经说了,是要大于n / 3,所以我思考后发现,满足条件的数最多也就2个,也就是说这种数的个数可能为0,1,2.那么首先遍历一遍数组,先找出候选众数,然后再遍历一遍,看这两个候选众数在原来的数组中出现的次数是否大于n / 3.如果满足,才能够加入到list中。
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 = Integer.MIN_VALUE;
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(count1 == 0)
{
num1 = temp;
count1 = 1;
}
else if(count2 == 0)
{
num2 = temp;
count2 = 1;
}
else
{
count1--;
count2--;
}
}
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;
}
这里应该可以证明> n / m,向下取整,那么最多满足条件的个数时m - 1。