C语言:找到数组中出现次数最多的元素

目录

一、前言

二、我的方法

三、完整代码


一、前言

前几天在leetcode刷题时遇到了这个需求,就来CSDN搜索解决方法。

逛了一大圈,发现最多的方法是:新建一个大小为原数组中最大值的数组(初始化为0),然后遍历原数组,例如遍历到元素a,那么新建数组nums[a]++。最终再遍历一次新建数组,就可以知道哪个元素出现次数最多,以及其出现次数。

先说说这种方法的弊端:

首先如果数组中的最大元素值很大,那么就要创建一个很大的数组,不说浪费空间的问题,问题是有没有这么大的一片连续空间,让我们去申请。

其次是这么长的数组,遍历的时间复杂度也相当高。

所以我个人认为这个方法其实并不可行。

二、我的方法

我自己想的一个方法,大家可以看看:

新建一个和原数组相同的数组Nums,并降序排序。设置度degree(即元素出现次数),默认大小为1(因为每个元素至少出现一次)。遍历数组Nums,如果某元素和其下一元素相等,则degree++,如果不相等,则degree重置为1。每遍历一个元素,都要取最大的degree。这样就能得到数组中出现最多次数元素的出现次数max。

int cmp(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}

//函数参数是要查找最多出现元素的数组以及该数组的大小
//int findShortestSubArray(int* nums, int numsSize) 

	int* Nums = (int*)malloc(sizeof(int) * numsSize);
    //拷贝原数组数据到新数组
	for (int i = 0; i < numsSize; i++)
	{
		Nums[i] = nums[i];
	}
	qsort(Nums, numsSize, sizeof(int), cmp);//升序排序新数组

	int degree = 1;//元素出现次数(度)
	int max = degree;//初始时,最大次数默认为1
    for (int i = 0; i < numsSize - 1; i++)
	{
		if (Nums[i] == Nums[i + 1])
		{
			degree++;
		}
		else
		{
			degree = 1;
		}

		max = (int)fmax(max, degree);//每遍历完一个元素,取最大的度
	}

得到元素最多出现的次数后,再次遍历数组Nums,如果某个元素的degree=max,说明该元素就是出现次数最多的元素。由于可能出现多个这样的元素,因此要设置一个最多出现元素的数组most,将所有最多出现次数的元素存储到这个数组中。

degree = 1;
	int* most = (int*)malloc(sizeof(int) * numsSize);
	memset(most, 0, sizeof(int) * numsSize);
	int mostsize = 0;
	for (int i = 0; i < numsSize - 1; i++)
	{
		if (Nums[i] == Nums[i + 1])
			degree++;
		else
			degree = 1;

		if (degree == max)
		{
			most[mostsize++] = Nums[i];
		}
	}

三、完整代码

int cmp(const void* e1, const void* e2)
{
    return *(int*)e1 - *(int*)e2;
}

int* find_mostnum(int* nums, int numsSize)
{
    int* Nums = (int*)malloc(sizeof(int) * numsSize);
    memcpy(Nums, nums, sizeof(numsSize) * numsSize);
    qsort(Nums, numsSize, sizeof(int), cmp);

    int degree = 1;
    int max = 0;
    for (int i = 0; i < numsSize - 1; i++)
    {
        if (Nums[i] == Nums[i + 1])
            degree++;
        else
            degree = 1;
        max = (int)fmax(max, degree);
    }

    degree = 1;
    int* ans = (int*)malloc(sizeof(int) * numsSize);
    memset(ans, 0, sizeof(int) * numsSize);
    int ansSize = 0;
    for (int i = 0; i < numsSize - 1; i++)
    {
        if (Nums[i] == Nums[i + 1])
            degree++;
        else
            degree = 1;
        if (degree == max)
            ans[ansSize++] = Nums[i];
    }

    return ans;
}

int main()
{
    int nums[] = { 1,2,2,3,1 };
    int* ret = find_mostnum(nums, 5);
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", ret[i]);
    }
    printf("\n");
    return 0;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南林yan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值