描述
给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一。
数组中只有唯一的主元素
样例
给出数组[1,2,1,2,1,3,3] 返回 1
挑战
要求时间复杂度为O(n),空间复杂度为O(1)。
思路: 这道题是主元素那道题目的升级版,在主元素1中,我们要求得元素数量大于n/2的那个元素。
如果要求时间复杂度为O(n),空间复杂度为O(1),我们可以这样求解。 维护一个candidate和一个counter,counter初始化为0,之后遍历整个数组,如果counter为0,则 candidate 设置为当前元素,并且 counter 设置为 1,如果 counter 不为 0,根据当前元素是否为 candidate 来递增或递减 counter。若数组非空,实际中,也可以直接把 candidate 赋值为数组的第一个元素。这样,最后那个candidate保存的就是我们要求得那个元素。
现在我们用同样得思路来求解主元素2这个问题。
首先,我们维护2个candidate和2个一一对应得counter。两个candidate不相同,且counter的更新方法与主元素1的相似。
如果当前元素不等于candidate1,则count1--;如果等于,count1++;如果count1=0,那么设置当前元素为candidate1,count=1;如此,循环遍历。
Java代码如下:
public static int majorityNumber(List<Integer> nums) {
// write your code here
int candidate1 = nums.get(0); int count1 = 0;
int candidate2 = nums.get(0); int count2 = 0;
int i = 0;
for (; i<nums.size() ; i++) {
if(nums.get(i)==candidate1){
count1++;
}else{
candidate2 = nums.get(i);
count2 = 1;
}
}
for (; i<nums.size();i++) {
int temp = nums.get(i);
if(temp==candidate1){
count1++;
}else if(temp==candidate2){
count2++;
}else{
count1--;
count2--;
}
if(count1==0){
candidate1 = temp;
}
if(count2==0){
candidate2 = temp;
}
}
// 验证candidate1,2
int len = nums.size()/3+1;
int count = 0;
for (int n: nums) {
if(n==candidate1){
count++;
}
}
if(count>=len){
return candidate1;
}else{
return candidate2;
}
}