力扣 229. 求众数 II

本文介绍摩尔投票法,一种高效查找序列中众数的算法。通过pairing和counting两个阶段,能在O(N)时间内找到出现次数超过序列长度特定比例的元素。文章给出具体实现代码,并提供适用于不同比例要求的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摩尔投票法是专门针对求序列中众数。 时间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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值