原题如下:删除任意一个在[1,N](N为自然数)的数字,然后将其剩下的数字打乱顺序放入数组A中,然后让找刚才那个被删除的数字。
要求:
时间复杂度在O(N) ,效率要高
分析下:解决这个问题编程的话,
我想到的有两种方法:一. 双层循环比较两个数组中的每个元素,此方法不满足题目要求,排除;
二. 要查找的被删除的数字=(删除前数组所有元素相乘)/(删除后打乱顺序的数组所有元素相乘);
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void ShowArrayElement(int *arr,int len)
{
for(int i=1;i<=len;i++)
printf("%d ",arr[i]);
printf("\n");
}
void InitArray(int *array,int len) //用1、2、3、4...len去初始化数组
{
for(int i=1;i<=len;i++)
array[i]=i;
}
long QiuNumberFoldBy(int *arr,int N) //求1、2、3、4...N的叠乘N!
{
int result=1;
for(int i=1;i<=N;i++)
result=result*arr[i];
return result;
}
void DisturbOrder(int *array,int len) //打乱一个元素个数为len的数组,元素值范围[1,len]
{
array[1]=rand()%len+1;
for(int i=2;i<=len;i++)
{
array[i]=rand()%len+1;
for(int j=1;j<i;j++)
{
if(array[i]==array[j])
{
i=i-1;
break;
}
}
}
}
void DeleteElement(int *arraySrc,int *arrayDes,int lenSrc,int deleteValue) //删除一个元素并打乱数组中的数据。
{
if(deleteValue>lenSrc||deleteValue<1)
printf("删除的值没在数组中");
DisturbOrder(arraySrc,lenSrc);
for(int i=1,j=1;i<=lenSrc;i++)
{
if(arraySrc[i]==deleteValue)
{
continue;
}
else
{
arrayDes[j]=arraySrc[i];
j++;
}
}
}
long find_Element(int *arrSrc,int *arrDes,int lenSrc) //结合源数组和删除后打乱的一数组寻找源数组中被删除的元素值
{
long result=0;
int len=lenSrc-1;
long ValDes=QiuNumberFoldBy(arrDes,len);
long ValSrc=QiuNumberFoldBy(arrSrc,lenSrc);
return ValSrc/ValDes;
}
void main()
{
while(getchar()!=32)
{
srand((unsigned)time(NULL));
int arrSrc[11]={0};
int arrDes[10]={0};
InitArray(arrSrc,10);
ShowArrayElement(arrSrc,10);
int Val=rand()%10+1;
DeleteElement(arrSrc,arrDes,10,Val); //此处随机给一个在1到10之间的要删除的数字,并将数组中其余数据打乱顺序存放入arrDes数组中
ShowArrayElement(arrDes,9);
int Valfind = find_Element(arrSrc,arrDes,10);
if(Valfind==Val)
printf("True\n");
printf("%d\n",Valfind);
}
}
运行结果如下 :解释下,下面第一行是[1,10]范围内的数字,第二行为删除了某个元素后打乱顺序的数组元素。最后一行是程序找出的被删除的数字。满足题目的要求,效率在O(N)。时间主要花在了计算数组元素叠乘上。