摩尔投票法是专门针对求序列中众数。 时间O(N),空间O(1)
摩尔投票分两个阶段,第一阶段 pairing 找出数量最多的元素,第二阶段 counting 检查是不是满足题意的最多的元素。(最多不一定满足题意。)
详细动画见
力扣题解
对于一个arr,
找出其中元素数量大于arr.length/2,则你最多只能找出 2-1=1 个
找出其中元素数量大于arr.length/n,则你最多只能找出 n-1 个
下面是找出length/3的代码
public static List<Integer> majorityElement(int[] nums) {
List<Integer> arr=new ArrayList<>();
if(nums==null || nums.length==0) return arr;
int length=nums.length;
int num1=nums[0],c1=0;
int num2=nums[0],c2=0;
for(int i:nums) { //paring阶段
if(num1==i)
c1++;
else if(num2==i) //tips:如果用这种写法 ,这里一定要 else if,如果用 if 有可能导致num1,num2重复,比如nums=[0,0,0]
c2++;
else if(c1==0) {
num1=i;
c1++;
}
else if(c2==0) {
num2=i;
c2++;
}
else {
c1--;
c2--;
}
}
c1=c2=0;
for(int i:nums) { //counting阶段
if(i==num1) c1++;
else if(i==num2) c2++; //tips: 这里也要用 else if
}
if(c1>length/3) arr.add(num1);
if(c2>length/3) arr.add(num2);
return arr;
}
对于多者的摩尔投票最重要的就是状态的更新,这是按照线性处理的,如果num1满足条件,则直接进行下次循环,不考虑num2,num3…
如果不满足则找出符合的那个直接进行下次循环,所以不用else if 的话,也可以用continue
下面是找出length/2的代码
public static List<Integer> majorityElement(int[] nums) {
List<Integer> arr=new ArrayList<>();
if(nums==null || nums.length==0) return arr;
int length=nums.length;
int num1=nums[0],c=0;
for(int i :nums) {
if(i==num1)
c++;
else
c--;
if(c==0) {
num1=i;
c++;
}
}
c=0;
for(int i:nums) {
if(i==num1) c++;
}
if(c>length/2) arr.add(num1);
return arr;
}
最后指出 counting阶段只是检验数量最大的数是不是大于length/n的,如果题目保证一定存在,则pairing阶段的结果就是正确ans