P18.12
有n个整数存放到一维数组A中,若数组中存在个数大于一半的元素,输出该元素,称其为主元素。
(1)算法的基本设计思想
由题设数组元素大小的限制,我们可以另外新建一个数组A',负责计算各元素个数。例如遍历后发现数组中6有5个,则A'[6]=5。以此类推。
(2)代码如下
#include <stdio.h>
#include <malloc.h>
#include <math.h>
unsigned int* array(unsigned int i);//C中不能新建数组元素为变量的数组,该函数用于实现这一功能
void main()
{
int countList;
scanf("%d", &countList);
unsigned int* A = array(countList);
unsigned int* Acount = array(countList);
int count;
printf("请输入数组元素\n");
for (count = 0; count < countList; count++)
{
scanf("%d", &A[count]);
}
for (count = 0; count < countList; count++)
{
Acount[A[count]]++;
}
for (count = 0; count < countList; count++)
{
if (Acount[count] >= countList / 2 + 1)
{
printf("主元素为%d\n", count);
break;
}
}
if(count==countList)
printf("无主元素");
}
unsigned int* array(unsigned int i)
{
unsigned int *arr;//指针用于指向数组的首地址
unsigned int j = 0;
arr = (unsigned int *)malloc(sizeof(int)*i);//分配数组地址空间
for (j = i; j > 0; j--)
arr[j - 1] = 0;
return arr;
}
(3)复杂度
时间复杂度O(n)
空间复杂度O(n)
老子就日了,自己只能想出来傻逼算法真是气炸。
较好的算法
(1)算法的基本设计思想
题设中我们可以知道,假设总的元素个数为10,那么主元素个数至少为6。现在以个数为6开始讨论。
设数组中第一个元素为主元素,计数值为1。下面看第二个元素,若与第一个相同,则计数值加一,否则减一。当计数值为0的时候,选择下一个元素作为新的主元素。直到最后。那么此时的主元素值可能是真的主元素值。之后检验。
对于原理,我们这样考虑,选择一种特殊情形如下
扫描二维码关注公众号,回复:
2652183 查看本文章
6564636266
这一数组的主元素为6。且是第一个元素就是主元素的特殊情况。那么我们可以看出,计数值一直是加一减一加一减一,且必定有至少两个主元素相邻的情况。而且总的来看,加一的次数比减一的次数多一。如果有两次连续的减一,那么则必有至少三个连续的加一。可以通过插队加以说明
6 6 6 6 6 6
其他的四个元素都插在这七个空隙之间。如果有两个插在同一空隙中,则共插了三个空隙,剩余四个。假设全插中间,则剩余的四个空隙是头,尾,和中间的两个,这样就是三个主元素相邻了。三个主元素相邻计数值为三,只有三个非主元素相邻才能使其为零,但是不存在,那么主元素的计数值就不为0。
这他妈考试的时候我怎么可能想出来啊。
(2)代码如下
#include <stdio.h>
#include <malloc.h>
#include <math.h>
unsigned int* array(unsigned int i);//C中不能新建数组元素为变量的数组,该函数用于实现这一功能
void main()
{
int countList;
scanf("%d", &countList);
unsigned int* A = array(countList);
int count;
printf("请输入数组元素\n");
for (count = 0; count < countList; count++)
{
scanf("%d", &A[count]);
}
int maybe = A[0];
int countmaybe=1;
for (count = 1; count < countList; count++)
{
if (countmaybe == 0)
maybe = A[count];
if (A[count] == maybe)
countmaybe++;
else
countmaybe--;
}
countmaybe = 0;
for (count = 0; count < countList; count++)
{
if (A[count] == maybe)
countmaybe++;
}
if(countmaybe >= countList / 2 + 1)
printf("主元素为%d\n", maybe);
else
printf("无主元素");
}
unsigned int* array(unsigned int i)
{
unsigned int *arr;//指针用于指向数组的首地址
unsigned int j = 0;
arr = (unsigned int *)malloc(sizeof(int)*i);//分配数组地址空间
for (j = i; j > 0; j--)
arr[j - 1] = 0;
return arr;
}
(3)复杂度
时间复杂度O(n)
空间复杂度O(1)