这让我疯狂:(
问题陈述:
输入了未排序的数组。接下来,用户提供了一组数字,程序应该打印该数组中给定数字的出现次数。
这应该在O(n)时间复杂度下运行。
实施例: 输入数组:[1,1,1,2,2,0]
收集数字:
1
2
1
0
输出:
3
2
3
1
约束:数组的大小可以是10 ^ 5,数字的集合大小可以是10 ^ 5
P.S:我用O(n ^ 2)
制作了一个代码#include<stdio.h>
#include<stdlib.h>
void main(){
int *n,size,key,count=0;
scanf("%d",&size);
n=(int*)malloc(size*sizeof(int));
for(int i=0;i<size;i++){
scanf("%d",&n[i]);
}
scanf("%d",&key);
for(int i=0;i<key;i++){
count=0;
int temp=0;
scanf("%d",&temp);
for(int j=0;j<size;j++){
if(temp==n[j])
count+=1;
}
printf("\n");
if(count==0){
printf("NOT PRESENT");
}
else{
printf("%d",count);
}
}
}
欢迎任何帮助:)
答案 0 :(得分:3)
元素范围很小。因此,为可能的值创建一个计数器数组,并为您找到的每个值增加计数。例如,如果找到2,则递增counter[2]
。
然后给出你的数字集合,只需进行数组查找即可获得计数。
答案 1 :(得分:2)
时间复杂度为O(max(m,n))其中m是数组的大小,n是集合的大小。所需空间为O(p),其中p是可能出现在数组中的整数范围。我们将使用p0来表示此范围的下限。
解决方案很简单:
答案 2 :(得分:0)
一种非常简单的方法是将结果数组的键放在值的位置。
我的C技能有点弱,但这里是伪C的方式(你必须调整它以使其正常工作:
int size = 10*10*10*10*10;
int[size] input = getInput();
int[size] results = new int[size](0); // fill array with zeros
for(int i = 0; i < size; i++) {
if (input[i] === -1)
break; // assuming -1 signifies the end of the input
output[input[i]]++; // increment the value at the index that matches the number by one
}
for(int i = 0; i < size; i++) {
if (output[i] === 0)
continue; // number wasn't in array
printf('%d', output[i]);
}
基本上,您将数组的输入放在匹配的输出索引中。
因此,如果您的输入为5,3,2,1,1,5,3,2,1
,则输入输出:
output[5]++;
output[3]++;
output[2]++;
output[1]++;
output[1]++;
output[5]++;
output[3]++;
output[2]++;
output[1]++;
生成一个如下所示的数组:
[0, 3, 2, 2, 0, 1]
然后你输出它,跳过零,因为它们不存在。
答案 3 :(得分:0)
你可以简单地创建一个10 ^ 5的数组并用0初始化它。现在迭代数组并增加数组中的值。就像你遇到5增量arr [5],现在你可以在O(1)时间内回答查询。
以下是java中的代码。
import java.util.Scanner;
public class test
{
public static void main(String args[])
{
Scanner in=new Scanner(System.in());
int n=s.nextInt();
int arr[]=new int[100001]; //Array is initialized 0
for(int i=0;i<n;i++)
{
int num=s.nextInt();
arr[num]++;
}
while(s.hasnextInt())
{
int p=s.nextInt();
System.out.println(arr[p]);
}
}
}