每日一题——多数元素

多数元素

题目链接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jwOf6Efu-1690383513222)(C:\Users\HUASHUO\AppData\Roaming\Typora\typora-user-images\image-20230726223326912.png)]

方法一:暴力解法

直接利用两层循环,外层循环用来枚举数组的每一个元素,内层循环用来计算每个元素出现的次数,这样就可以求出多数元素了。

显然,这个方法的时间复杂度为O(N^2),效率太低。

int majorityElement(int* nums, int numsSize) {
	int max_index = 0;	//用来记录多数元素的下标
	int temp = 0;	//用来统计每个元素出现的次数
	int max = 0;	//用来记录出现的最大次数
    
	for (int i = 0; i < numsSize; i++)
	{
		temp = 0;	//每一次都是对一个新的元素记录,因此temp要置零
        
        //如果出现重复元素,那么就temp++
		for (int j = 0; j < numsSize; j++)
		{
			if (nums[i] == nums[j])
				temp++;
		}
        //如果temp大于最大次数,那么就更新多数元素下标,同时更新max
		if (temp > max)
		{
			max_index = i;
			max = temp;
		}
	}
    //返回多数元素
	return nums[max_index];
}

方法二:排序

先给出结论:如果一个有序数组中存在多数元素(出现次数大于n/2),那么下标为n / 2处的元素就是多数元素

下面通过画图来分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ga8YKyIN-1690383513223)(C:\Users\HUASHUO\AppData\Roaming\Typora\typora-user-images\image-20230726223423877.png)]

我们利用快速排序qsort来实现,时间复杂度为O(NlongN),效率有所提高,但仍无法满足题目要求

int compar(const void* num1, const void* num2)
{
    return *(int*)num1 - *(int*)num2;
}
int majorityElement(int* nums, int numsSize){
    //排序
    qsort(nums,numsSize,sizeof(int),compar);
    //返回多数元素
    return nums[numsSize/2];
}

(推荐)方法三:互拼法(Boyer-Moore 投票算法)

我们来举一个形象的例子来解释这个算法:

假设有100个士兵,由于多数元素必然大于n/2,那我们假设多数元素士兵为51个,其他元素士兵为49个,这100个士兵一起去占领一块高地(相同士兵共存,不同士兵相消)

  1. 第一个到来的士兵,直接插上自己阵营的旗帜占领这块高地,现存兵力 count = 1。
  2. 如果新来的士兵和前一个士兵是同一阵营,则集合起来占领高地,~~~~现存兵力 count++;
  3. 如果新来到的士兵不是同一阵营,则前方阵营派一个士兵和它同归于尽。 此时前方阵营兵力count --。
  4. 当下一个士兵到来,发现前方阵营已经没有兵力(双方死光),新士兵就成了领主,现存兵力 count ++。

就这样各路军阀一直以这种以一敌一同归于尽的方式厮杀下去,直到少数阵营都死光,那么最后剩下的几个必然属于多数阵营。(多数阵营 51个,少数阵营只有49个,死剩下的2个就是多数阵营的人)

这一题也一样,数组的第一个元素就是第一个士兵,,同时我们假设第一个元素就是要返回的多数元素temp,接下来遍历整个数组,如果遇到相同元素,那么count++,否则count--,如果count减为0,那么下一个元素就会成为多数元素,temp也要改变,最后遍历完数组得到的temp就是未被抵消的元素,即多数元素

这样,只需要遍历一遍数组,就可以得到想要的结果,时间复杂度为O(N)

int majorityElement(int* nums, int numsSize){
    int temp = nums[0];
    int count = 0;
    for(int i = 0; i < numsSize; i++)
    {
        if(temp == nums[i])
            count++;
        else
            count--;
        if(count == 0)
            temp = nums[i + 1];
    }
    return temp;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forward♞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值